Skip to content

[Python] enforce read bounds in Table - #9281

Open
ManoharPaturi wants to merge 1 commit into
google:masterfrom
ManoharPaturi:pr-py-table
Open

ManoharPaturi wants to merge 1 commit into
google:masterfrom
ManoharPaturi:pr-py-table

Conversation

@ManoharPaturi

Copy link
Copy Markdown

Problem

The Python Table accessors trust offsets that come from the buffer itself when reading untrusted data:

  • struct.unpack_from silently accepts negative offsets, reading relative to the end of the buffer, so Indirect/Offset with a negative computed target returns data from the wrong position with no error,
  • String slices Bytes[start : start + length], and Python slicing clamps out-of-range ranges, so a malformed length silently returns a truncated string (or an empty one for huge unsigned lengths like 0xffffffff),
  • Vector returns a start position beyond the buffer without complaint.

Change

Adds a _CheckOffset(buf, offset, size, what) guard:

  • Offset validates the resolved vtable position (negative soffset no longer wraps),
  • Indirect validates the computed target,
  • String validates start + length against the buffer size before slicing,
  • Vector validates the computed start (an empty vector may start exactly at the end).

Malformed buffers now raise IndexError with a clear message instead of silently producing wrong values. Mirrors the read-bounds enforcement direction the Swift port has adopted (#9277), applied to the Python port (companion to the TS-port change in #9280).

Test plan

  • New tests/py_table_bounds_test.py: negative/out-of-range indirect and vtable targets, clamped and huge-length strings, vector start past the end, plus valid-target sanity cases — 10/10 pass
  • On master, the same tests fail with wrong values instead of raising — confirming the silent misparse behavior
  • tests/py_flexbuffers_test.py unchanged and passing (60/60) after the change
  • (py_test.py requires flatc-generated code and runs in CI)

Offsets come from the buffer itself when reading untrusted data.
struct.unpack_from silently accepts negative offsets (reading relative
to the buffer end) and slicing clamps out-of-range ranges, so malformed
buffers previously produced wrong values instead of errors.

Adds a _CheckOffset guard to Offset, Indirect, String, and Vector, and
rejects huge unsigned string lengths, raising IndexError with a clear
message instead. Mirrors the read-bounds enforcement the Swift port
adopted (google#9277).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant