kaitai-io / kaitai_struct

Kaitai Struct: declarative language to generate binary data parsers in C++ / C# / Go / Java / JavaScript / Lua / Nim / Perl / PHP / Python / Ruby
https://kaitai.io
4.04k stars 199 forks source link

Parse instance with `contents` is not validated #1011

Open generalmimon opened 1 year ago

generalmimon commented 1 year ago

Since 0.9, KSC doesn't generate any validation for a positional instance which uses the contents key:

meta:
  id: contents_fail_inst
instances:
  e:
    pos: 0
    contents: [0xc8]

In this case, the generated code only reads one byte in e:

class ContentsFailInst < Kaitai::Struct::Struct
  # ...
  def e
    return @e unless @e.nil?
    _pos = @_io.pos
    @_io.seek(0)
    @e = @_io.read_bytes(1)
    @_io.seek(_pos)
    @e
  end

But when valid is used, the validation works:

meta:
  id: valid_fail_inst
instances:
  e:
    pos: 0
    size: 1
    valid: '[0xc8]'
class ValidFailInst < Kaitai::Struct::Struct
  # ...
  def e
    return @e unless @e.nil?
    _pos = @_io.pos
    @_io.seek(0)
    @e = @_io.read_bytes(1)
    @_io.seek(_pos)
    raise Kaitai::Struct::ValidationNotEqualError.new([200].pack('C*'), e, _io, "/instances/e") if not e == [200].pack('C*')
    @e
  end

So it looks like we've forgotten about this case (and of course there is no test for it in our test suite). In fact, it's even a 0.9 regression (that's right, another regression related to contents), because contents in a parse instance used to work in 0.8:

class ContentsFailInst < Kaitai::Struct::Struct
  # ...
  def e
    return @e unless @e.nil?
    _pos = @_io.pos
    @_io.seek(0)
    @e = @_io.ensure_fixed_contents([200].pack('C*'))
    @_io.seek(_pos)
    @e
  end