Skip to content

pxf: DatasetReader reads under the caller's bytes and depth limits (#160) - #162

Merged
trendvidia merged 2 commits into
mainfrom
dataset-bytes-limit-160
Nov 7, 2026
Merged

trendvidia merged 2 commits into
mainfrom
dataset-bytes-limit-160

Conversation

@bfrancojr

Copy link
Copy Markdown
Collaborator

Fixes #160.

DatasetReader now reads under the caller's max_bytes_literal_length and max_nesting_depth, as protowire-go does. Before, a caller who lowered the bytes limit still got a row whose b"…" cell was past it, and a caller who raised it had the cell refused.

Changes

  1. Rows: ParseDatasetRow takes the bytes-literal limit, and DatasetReader::Next passes opts_.max_bytes_literal_length, with 0 meaning the default. Only the nesting depth reached it before.
  2. Header (absorbed, same cause): ReadHeader called Parse(header) with default options, so a @header block and the @dataset line ignored both limits. It now passes the caller's depth and bytes limits. Go's NewDatasetReader doc says "the header and every row are parsed under its MaxNestingDepth and MaxBytesLiteralLength".

Evidence

Same inputs through protowire-go 903b4a7 (UnmarshalOptions{...}.NewDatasetReader) and this branch:

Input Limit protowire-go This PR
row with a 192-byte b"…" bytes 191 2:3: bytes literal decodes to more than MaxBytesLiteralLength=191 bytes refused, same text at 1:3: (see below)
same bytes 192, and 0 accepted accepted
@header with a 192-byte b"…" bytes 191 1:21: bytes literal decodes to more than MaxBytesLiteralLength=191 bytes identical
same 0 accepted accepted
@header four blocks deep depth 3 1:25: nesting depth exceeds MaxNestingDepth=3 identical
same depth 4 accepted accepted
  • Two new tests, HardeningDataset.RowBytesLiteralUnderTheCallersLimit and HardeningDataset.HeaderUnderTheCallersLimits. Each fails with its half of the fix reverted (checked by hand for both).
  • Locally: 727/727 tests pass.

Not in this PR

A row error's line counts from the start of the row, where Go counts from the start of the stream (1:3: here vs Go's 2:3:). That predates this change and has its own mechanism, so it's filed as #161.

…#160)

DatasetReader::Next passed only the nesting depth to ParseDatasetRow,
which read every row under kMaxBytesLiteralLength. A caller who lowered
max_bytes_literal_length still got a row with a b"..." cell past it,
and one who raised it had that cell refused. protowire-go reads rows
under the caller's limit (dataset_stream.go: maxBytesLiteral:
tr.lim.maxBytesLiteral).

ParseDatasetRow now takes the limit, and the reader passes
opts_.max_bytes_literal_length, with 0 meaning the default. The new test
reads a 192-byte cell at limits 191 (refused, with the lexer's text),
192 and 0 (both accepted). With the reader's limit forced back to the
default, the test fails at 191.
ReadHeader called Parse(header) with default ParseOptions, so a @Header
block or the @dataset line was read under kMaxNestingDepth and
kMaxBytesLiteralLength whatever the options said. protowire-go parses
"the header and every row ... under its MaxNestingDepth and
MaxBytesLiteralLength" (NewDatasetReader's doc).

The new test checks both limits at Create. Measured against protowire-go
903b4a7 on the same inputs: a 192-byte b"..." in @Header is refused at
191 with 1:21: bytes literal decodes to more than
MaxBytesLiteralLength=191 bytes, and a header four blocks deep is
refused at depth 3 with 1:25: nesting depth exceeds MaxNestingDepth=3
and accepted at 4. This port now gives the same text and positions.
With the header fix reverted, the test fails.
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

Successfully merging this pull request may close these issues.

DatasetReader ignores UnmarshalOptions::max_bytes_literal_length when it parses a row

2 participants