S2LaxPolygonShape::Init: Validate loop_starts - #681
Open
sushant-me wants to merge 2 commits into
Open
sushant-me wants to merge 2 commits into
sushant-me wants to merge 2 commits into
Conversation
Both S2LaxPolygonShape::Init and EncodedS2LaxPolygonShape::Init decoded
`loop_starts` without checking it, and `chain_edge()` indexes
`vertices_[loop_starts_[i] + j]` -- so offsets that are inconsistent with the
vertex array read outside it.
Measured under AddressSanitizer, against a malformed encoded index:
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 24
#0 EncodedS2PointVector::At encoded_s2point_vector.h:166
google#2 EncodedS2LaxPolygonShape::chain_edge s2lax_polygon_shape.h:306
google#3 EncodedS2LaxPolygonShape::edge s2lax_polygon_shape.cc:360
The fix requires the offsets to start at 0, be non-decreasing, and end at the
vertex count, in both decode paths.
The test asserts that Init() rejects such bytes, which is what makes the
regression visible in a normal build: an out-of-bounds read does not fault
without a sanitizer, so a traversal-based test would pass either way.
s2lax_polygon_shape_test --gtest_filter='*RejectsInconsistentLoopStarts*'
before: [ FAILED ] 1 test.
after: [ PASSED ] 1 test.
It corrupts only the "starts at 0" rule, leaving the offsets non-decreasing and
ending at the vertex count, so a check that covered only monotonicity or only
the final offset would still pass it.
Suites on this branch: s2lax_polygon_shape_test 21/21,
encoded_s2shape_index_test 9/9, mutable_s2shape_index_test 29/29.
Split out of google#675 as requested there, and independent of google#680.
The macos-15-intel job ended with "The operation was canceled." inside the build step; the test steps in the same job reported 100% of 1878 tests passed. No source change: this commit only re-triggers the workflow.
Author
|
Note on the cancelled check: inside the I pushed an empty commit to re-trigger the workflow (no source change); the new runs are waiting on |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Split out of #675, per the request there. Independent of #680.
The bug
chain_edge()computesvertices_[loop_starts_[i] + j], and neitherS2LaxPolygonShape::InitnorEncodedS2LaxPolygonShape::Initvalidated theoffsets they had just decoded. An encoding whose
loop_startsare inconsistentwith the vertex array therefore reads outside it.
Confirmed with AddressSanitizer rather than inferred — the read is real but does
not fault in a normal build:
The change
Require the offsets to start at 0, be non-decreasing, and end at the vertex
count, in both the eager and the lazy decode path.
Verification
The test builds a valid two-loop shape, encodes it, and then flips only the
"starts at 0" rule — leaving the offsets non-decreasing and ending at the vertex
count, so a check covering only monotonicity or only the final offset still
passes it. It asserts the layout of the tail before corrupting it, so a change
to the encoding fails loudly instead of silently patching the wrong byte.
Asserting on
Init()'s return value rather than on a traversal is deliberate:an out-of-bounds read does not fault without a sanitizer, so a test that only
walked the shape would pass both before and after.
Suites on this branch:
s2lax_polygon_shape_test21/21,encoded_s2shape_index_test9/9,mutable_s2shape_index_test29/29.