zeek/spicy

`&max-size` has effect on how much data is consumed

bbannier opened this issue · 0 comments

I would expect &max-size to inject a post-condition into parsing, but not have an effect on how much data is consumed (unless there is an error). This is not the case, e.g., in below reproducer regardless of whether &max-size was used or not, rest should always be b"BC",

# @TEST-EXEC: printf '\x01_BC' | spicy-dump -d %INPUT >>output2 2>&1
# @TEST-EXEC: printf '\x00_BC' | spicy-dump -d %INPUT >>output2 2>&1

module foo;

public type X = unit {
    use_max_size: uint8 &convert=cast<bool>($$);

    switch (self.use_max_size) {
        True -> xs: bytes &until=b"_" &max-size=1;
        False -> xs: bytes &until=b"_";
    };

    rest: bytes &eod;
};

Instead the following output is produced:

foo::X {
  use_max_size: True
  xs:
  rest: C
}
foo::X {
  use_max_size: False
  xs:
  rest: BC
}

The error is in how &max-size sets the next position,

pstate.ncur = builder()->addTmp("ncur", builder::memberCall(state().cur, "advance", {*length}));

Contrary to what we currently do, &max-size is completely different from &size wrt. ncur which depends on what was actually parsed and cannot be known or set before.

I came across this while working on #1652.