Skip to content

AVRO-4276: [C++] Fix INT64_MIN overflow in doDecodeItemCount()#3843

Open
iemejia wants to merge 1 commit into
apache:mainfrom
iemejia:avro-4275-cpp-int64min-overflow
Open

AVRO-4276: [C++] Fix INT64_MIN overflow in doDecodeItemCount()#3843
iemejia wants to merge 1 commit into
apache:mainfrom
iemejia:avro-4275-cpp-int64min-overflow

Conversation

@iemejia

@iemejia iemejia commented Jul 11, 2026

Copy link
Copy Markdown
Member

Summary

Fix signed integer overflow in BinaryDecoder::doDecodeItemCount() when the decoded block count equals INT64_MIN.

Problem

The existing negation idiom -(result + 1) + 1 still overflows on the final + 1 when result == INT64_MIN (since -INT64_MIN is not representable in int64_t). This is undefined behavior in C++ and could result in the decoder returning 2^63 as the item count for both arrays and maps.

Fix

  • Add an explicit guard: if result == INT64_MIN, throw an Exception immediately.
  • For all other negative values, use simple -result which is well-defined.

Tests

Added two new test cases:

  • testArrayInt64MinBlockCount — verifies arrayStart() throws on a zigzag-encoded INT64_MIN block count.
  • testMapInt64MinBlockCount — verifies mapStart() throws on the same input.

This is the C++ counterpart to the C fix in commit 271de63.

@github-actions github-actions Bot added the C++ Pull Requests for C++ binding label Jul 11, 2026
@iemejia iemejia changed the title AVRO-4275: [C++] Fix INT64_MIN overflow in doDecodeItemCount() AVRO-4276: [C++] Fix INT64_MIN overflow in doDecodeItemCount() Jul 11, 2026
@iemejia iemejia force-pushed the avro-4275-cpp-int64min-overflow branch from 399568b to 5855770 Compare July 11, 2026 08:35
@iemejia iemejia requested a review from Copilot July 11, 2026 08:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a C++ undefined-behavior edge case in BinaryDecoder::doDecodeItemCount() where a zigzag-decoded block count of INT64_MIN could trigger signed overflow and yield an invalid item count.

Changes:

  • Add an explicit INT64_MIN guard in BinaryDecoder::doDecodeItemCount() and throw an Exception instead of overflowing.
  • Simplify negative-count handling to use -result for all other negative values.
  • Add unit tests to ensure arrayStart() / mapStart() reject a zigzag-varint encoding of INT64_MIN.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
lang/c++/impl/BinaryDecoder.cc Adds an INT64_MIN rejection path and avoids signed overflow when converting negative block counts to size_t.
lang/c++/test/CodecTests.cc Adds regression tests covering INT64_MIN as an array/map block count to ensure an exception is thrown.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +166 to +168
if (result == INT64_MIN) {
throw Exception("Invalid negative block count");
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — now includes the offending value in the message ("Invalid negative block count: {}") consistent with other exceptions in this file.

Replace the -(result + 1) + 1 idiom (which still overflows on the
final + 1 when result == INT64_MIN) with an explicit INT64_MIN guard
that throws an exception, followed by simple negation for all other
negative values.

Add unit tests for both arrayStart() and mapStart() to verify that a
zigzag-encoded INT64_MIN block count is properly rejected.

Assisted-by: GitHub Copilot:claude-opus-4.6
@iemejia iemejia force-pushed the avro-4275-cpp-int64min-overflow branch from 5855770 to fa3e46e Compare July 11, 2026 08:50
@iemejia iemejia requested a review from Copilot July 11, 2026 08:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@iemejia iemejia requested review from RyanSkraba and martin-g July 11, 2026 09:00
@iemejia

iemejia commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

@martin-g @RyanSkraba apparently the previous fix for AVRO-4228 #3646 was missing one corner case.

@RyanSkraba both of those fixes should be cherry-picked into the next 1.12 release

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

Labels

C++ Pull Requests for C++ binding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants