Skip to content

Commit fb101ec

Browse files
authored
Merge pull request #3368 from trailofbits/3367-windows-readline
Adds support for readline on Windows
2 parents 2cdd613 + 2014735 commit fb101ec

25 files changed

+347
-77
lines changed

.github/workflows/pythonpublish.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ jobs:
2222
python-version: '3.x'
2323
- name: Install dependencies
2424
run: |
25-
curl -LO https://github.com/kaitai-io/kaitai_struct_compiler/releases/download/0.9/kaitai-struct-compiler_0.9_all.deb
26-
sudo apt-get install ./kaitai-struct-compiler_0.9_all.deb
2725
python -m pip install --upgrade pip
2826
pip install setuptools wheel twine
2927
- name: Build and publish

.github/workflows/tests.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ on:
1212
jobs:
1313
build:
1414

15-
runs-on: ubuntu-latest
1615
strategy:
1716
matrix:
18-
python-version: [3.7, 3.8, 3.9, "3.10"]
17+
os: [ubuntu-latest] # windows-latest, macos-latest,
18+
python-version: ["3.7", "3.8", "3.9", "3.10"]
19+
20+
runs-on: ${{ matrix.os }}
1921

2022
steps:
2123
- uses: actions/checkout@v2
@@ -25,10 +27,8 @@ jobs:
2527
uses: actions/setup-python@v1
2628
with:
2729
python-version: ${{ matrix.python-version }}
28-
- name: Install dependencies
30+
- name: Install Python Dependencies
2931
run: |
30-
curl -LO https://github.com/kaitai-io/kaitai_struct_compiler/releases/download/0.9/kaitai-struct-compiler_0.9_all.deb
31-
sudo apt-get install ./kaitai-struct-compiler_0.9_all.deb
3232
python -m pip install --upgrade pip
3333
pip install setuptools
3434
pip install .[dev]

file

Submodule file updated 204 files

polyfile/kaitai/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
kaitai-struct-compiler-0.9

polyfile/kaitai/compiler.py

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,32 @@
44
This module automates compilation of Kaitai Struct definitions into Python code.
55
66
This script is called from PolyFile's setup.py to compile the entire Kaitai Struct format library at build time.
7-
Therefore, this script should always be self-contained and not require any dependencies outside of the Python standard
7+
Therefore, this script should always be self-contained and not require any dependencies other than the Python standard
88
library.
99
1010
"""
11+
from io import BytesIO
1112
import json
13+
import os
1214
from pathlib import Path
1315
import shutil
16+
import stat
1417
import subprocess
15-
from typing import Iterable, List, Union
18+
import sys
19+
from typing import Iterable, List, Optional, Union
20+
from urllib.request import urlopen
21+
from zipfile import ZipFile
1622

1723

18-
KAITAI_COMPILER_NAME: str = "kaitai-struct-compiler"
24+
if os.name == "nt":
25+
KAITAI_COMPILER_NAME: str = "kaitai-struct-compiler.bat"
26+
else:
27+
KAITAI_COMPILER_NAME = "kaitai-struct-compiler"
28+
29+
30+
COMPILER_DIR = Path(__file__).absolute().parent / "kaitai-struct-compiler-0.9"
31+
COMPILER_BIN_DIR = COMPILER_DIR / "bin"
32+
COMPILER_BIN = COMPILER_BIN_DIR / KAITAI_COMPILER_NAME
1933

2034

2135
class KaitaiError(RuntimeError):
@@ -31,10 +45,6 @@ def __str__(self):
3145
return f"{self.ksy_file}: {super().__str__()}"
3246

3347

34-
def has_kaitai_compiler() -> bool:
35-
return shutil.which(KAITAI_COMPILER_NAME) is not None
36-
37-
3848
class CompiledKSY:
3949
def __init__(self, class_name: str, python_path: Union[str, Path], dependencies: Iterable["CompiledKSY"] = ()):
4050
self.class_name: str = class_name
@@ -48,19 +58,46 @@ def __repr__(self):
4858
f"dependencies={self.dependencies!r})"
4959

5060

51-
def compile(ksy_path: Union[str, Path], output_directory: Union[str, Path]) -> CompiledKSY:
61+
def install_compiler():
62+
resp = urlopen("https://github.com/kaitai-io/kaitai_struct_compiler/releases/download/0.9/"
63+
"kaitai-struct-compiler-0.9.zip")
64+
zipfile = ZipFile(BytesIO(resp.read()))
65+
COMPILER_DIR.mkdir(exist_ok=True)
66+
zipfile.extractall(COMPILER_DIR.parent)
67+
if COMPILER_BIN.exists():
68+
COMPILER_BIN.chmod(COMPILER_BIN.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
69+
sys.stderr.write(f"Installed the Kaitai Struct Compiler to {COMPILER_BIN}\n")
70+
71+
72+
def compiler_path(auto_install: bool = True) -> Optional[Path]:
73+
if COMPILER_BIN.exists():
74+
return COMPILER_BIN
75+
global_path = shutil.which(KAITAI_COMPILER_NAME)
76+
if global_path is not None:
77+
return Path(global_path)
78+
if not auto_install:
79+
return None
80+
install_compiler()
81+
return compiler_path(auto_install=False)
82+
83+
84+
def compile(ksy_path: Union[str, Path], output_directory: Union[str, Path], auto_install: bool = True) -> CompiledKSY:
5285
"""Returns the list of compiled KSYs; the original spec being first, followed by its dependencies"""
53-
if not has_kaitai_compiler():
54-
raise KaitaiError(f"{KAITAI_COMPILER_NAME} not found! Please make sure it is in your PATH")
86+
compiler = compiler_path(auto_install=auto_install)
87+
if compiler is None:
88+
raise KaitaiError(f"{KAITAI_COMPILER_NAME} not found! Please make sure it is in your PATH. "
89+
f"See https://kaitai.io/#download")
90+
91+
# sys.stderr.write(f"Using Kaitai Struct Compiler: {compiler!s}\n")
5592

5693
if not isinstance(output_directory, Path):
5794
output_directory = Path(output_directory)
5895

5996
output_directory.mkdir(parents=True, exist_ok=True)
6097

6198
cmd = [
62-
KAITAI_COMPILER_NAME, "--target", "python", "--outdir", str(output_directory), str(ksy_path),
63-
"--debug", "--ksc-json-output", "-I", Path.cwd(), "--python-package", "polyfile.kaitai.parsers"
99+
str(compiler), "--target", "python", "--outdir", str(output_directory), str(ksy_path),
100+
"--debug", "--ksc-json-output", "-I", str(Path.cwd()), "--python-package", "polyfile.kaitai.parsers"
64101
]
65102

66103
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -96,7 +133,12 @@ def compile(ksy_path: Union[str, Path], output_directory: Union[str, Path]) -> C
96133

97134
if __name__ == "__main__":
98135
import argparse
99-
import sys
136+
137+
if len(sys.argv) == 2 and sys.argv[1] == "--install":
138+
if compiler_path() is None:
139+
sys.exit(1)
140+
else:
141+
sys.exit(0)
100142

101143
parser = argparse.ArgumentParser(description="A Kaitai Struct to Python compiler")
102144
parser.add_argument("KSY_PATH", type=str, help="path to the Kaitai Struct definition file")

polyfile/kaitai/parsers/compressed_resource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class CompressedResource(KaitaiStruct):
3939
4040
4141
.. seealso::
42-
Source - https://github.com/dgelessus/python-rsrcfork/tree/master/rsrcfork/compress
42+
Source - https://github.com/dgelessus/python-rsrcfork/tree/f891a6e/src/rsrcfork/compress
4343
"""
4444
SEQ_FIELDS = ["header", "compressed_data"]
4545
def __init__(self, _io, _parent=None, _root=None):

polyfile/kaitai/parsers/dcmp_0.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Dcmp0(KaitaiStruct):
4040
with the main difference that it operates mostly on single bytes rather than two-byte units.
4141
4242
.. seealso::
43-
Source - https://github.com/dgelessus/python-rsrcfork/tree/master/rsrcfork/compress/dcmp0.py
43+
Source - https://github.com/dgelessus/python-rsrcfork/blob/f891a6e/src/rsrcfork/compress/dcmp0.py
4444
"""
4545
SEQ_FIELDS = ["chunks"]
4646
def __init__(self, _io, _parent=None, _root=None):

polyfile/kaitai/parsers/dcmp_1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Dcmp1(KaitaiStruct):
3737
such as text.
3838
3939
.. seealso::
40-
Source - https://github.com/dgelessus/python-rsrcfork/tree/master/rsrcfork/compress/dcmp1.py
40+
Source - https://github.com/dgelessus/python-rsrcfork/blob/f891a6e/src/rsrcfork/compress/dcmp1.py
4141
"""
4242
SEQ_FIELDS = ["chunks"]
4343
def __init__(self, _io, _parent=None, _root=None):

polyfile/kaitai/parsers/dcmp_2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Dcmp2(KaitaiStruct):
3131
to differentiate literals and table references.
3232
3333
.. seealso::
34-
Source - https://github.com/dgelessus/python-rsrcfork/tree/master/rsrcfork/compress/dcmp2.py
34+
Source - https://github.com/dgelessus/python-rsrcfork/blob/f891a6e/src/rsrcfork/compress/dcmp2.py
3535
"""
3636
SEQ_FIELDS = ["custom_lookup_table", "data", "last_byte"]
3737
def __init__(self, len_decompressed, header_parameters_with_io, _io, _parent=None, _root=None):

0 commit comments

Comments
 (0)