Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional substructure fields do not work #25

Closed
mikewadsten opened this issue Nov 18, 2015 · 1 comment
Closed

Conditional substructure fields do not work #25

mikewadsten opened this issue Nov 18, 2015 · 1 comment

Comments

@mikewadsten
Copy link
Contributor

I would expect to be able to have a conditional SubstructureField, but that doesn't seem to actually work.

Example:

from suitcase.structure import Structure
from suitcase.fields import SubstructureField, ConditionalField, UBInt8


class Substruct1(Structure):
    cond = UBInt8()


class Substruct2(Structure):
    f1 = UBInt8()
    f2 = UBInt8()


class Substruct3(Structure):
    f31 = UBInt8()
    f32 = UBInt8()


class Struct(Structure):
    header = SubstructureField(Substruct1)
    s2 = ConditionalField(SubstructureField(Substruct2),
                          condition=lambda m: m.header.cond == 0)
    s3 = ConditionalField(SubstructureField(Substruct3),
                          condition=lambda m: m.header.cond == 0)


print("If the field(s) are not present...")
print(Struct.from_data('\x01'))

print("\nIf the field(s) are present...")
print(Struct.from_data('\x00\x11\x22\x33\x44'))

Output:

If the field(s) are not present...
Struct (
  header=Substruct1 (
  cond=1,
),
  s2=<ConditionalField: not included>,
  s3=<ConditionalField: not included>,
)

If the field(s) are present...
Traceback (most recent call last):
  File "condsubstruct.py", line 31, in <module>
    print(Struct.from_data('\x00\x11\x22\x33\x44'))
  File "/home/mike/.envs/suitcase/lib/python2.7/site-packages/suitcase/structure.py", line 247, in from_data
    m.unpack(data)
  File "/home/mike/.envs/suitcase/lib/python2.7/site-packages/suitcase/structure.py", line 300, in unpack
    return self._packer.unpack(data, trailing)
  File "/home/mike/.envs/suitcase/lib/python2.7/site-packages/suitcase/structure.py", line 61, in unpack
    self.unpack_stream(stream)
  File "/home/mike/.envs/suitcase/lib/python2.7/site-packages/suitcase/structure.py", line 138, in unpack_stream
    (name, length, len(data)))
suitcase.exceptions.SuitcaseParseError: While attempting to parse field 's2' we tried to read None bytes but we were only able to read 4.

If I had to guess, it might have something to do with SubstructureField returning None from bytes_required. But I'm not sure. I might dig into this more later tonight.

@mikewadsten
Copy link
Contributor Author

I did some more digging, and it looks like the problem is that Packer doesn't see ConditionalField as equivalent to s SubstructureField, and so it assumes it to be greedy.

I have a working fix, but haven't written the unit tests for it yet.

mikewadsten added a commit to mikewadsten/python-suitcase that referenced this issue Nov 19, 2015
TODO: Write unit tests to completely verify fix.

Fixes digidotcom#25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant