Skip to content

Navigation Menu

Sign in
Sign up

ORC-2166: [C++] Guard C++ integer arithmetic against overflow - #2622

Open
ffacs wants to merge 3 commits into
apache:main from
ffacs:string-direct-length-overflow
Open

ORC-2166: [C++] Guard C++ integer arithmetic against overflow #2622
ffacs wants to merge 3 commits into
apache:main from
ffacs:string-direct-length-overflow

Conversation

@ffacs

@ffacs ffacs commented May 12, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

This PR adds reusable checked integer arithmetic helpers for the C++ code: addWithOverflow and multiplyWithOverflow.

The patch uses these helpers to reject overflow-prone arithmetic in reader and buffer paths, including direct string length accumulation, list/map length accumulation, dictionary offsets, float/double skip byte counts, union child counts, DataBuffer allocation sizes, BlockBuffer size/capacity calculations, and list/map vector offset capacity calculations.

Regression tests were added for the overflow helpers and malformed string/list/map length streams.

Why are the changes needed?

Malformed ORC files can provide invalid or extremely large values in length streams. Negative lengths or overflowing length sums can cause unchecked integer wraparound, incorrectly sized allocations, wrapped offsets, or unsafe skip/copy behavior.

Centralizing checked arithmetic makes these cases fail cleanly before unsafe allocation or memory access. Reader-facing malformed input now fails with ParseError.

How was this patch tested?

Ran the full C++ test target:

 cmake --build build --target test-out

Result:

1/2 Test #1: orc-test .... Passed
2/2 Test #2: tool-test .... Passed

100% tests passed, 0 tests failed out of 2

Also ran targeted tests during development for the new overflow checks.

Was this patch authored or co-authored using generative AI tooling?

Yes. Generated with OpenAI Codex.

Comment thread c++/src/ColumnReader.cc Outdated
hasNegativeLength |= value < 0;
size_t length = static_cast<size_t>(value);
size_t nextTotalLength = totalLength + length;
hasLengthOverflow |= nextTotalLength < totalLength;

@dongjoon-hyun dongjoon-hyun May 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Like skip() method, shall we throw here instead of waiting for the whole loop is finished?

@ffacs ffacs changed the title (削除) ORC-2166: [C++] Validate string lengths in direct encoding reader (削除ここまで) (追記) ORC-2166: [C++] Guard C++ integer arithmetic against overflow (追記ここまで) May 24, 2026
ffacs force-pushed the string-direct-length-overflow branch from ffa2af2 to 0c3a0c7 Compare May 24, 2026 13:39
ffacs force-pushed the string-direct-length-overflow branch from 0c3a0c7 to 266b26b Compare May 24, 2026 13:46
wgtmac requested a review from Copilot May 26, 2026 02:11

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

This PR introduces reusable checked integer arithmetic helpers in the C++ codebase and applies them across multiple reader/allocation paths to prevent integer overflow from malformed ORC input (failing fast instead of wrapping into unsafe sizes/offsets).

Changes:

  • Add addWithOverflow / multiplyWithOverflow helpers and unit tests for overflow behavior.
  • Harden reader logic (string/list/map/union/dictionary paths) against negative lengths and overflowing length accumulation.
  • Add overflow-safe sizing logic for vector offsets, DataBuffer allocation sizing, and block buffer size/capacity calculations.

Reviewed changes

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

Show a summary per file
File Description
c++/test/TestUtils.cc Adds unit tests for the new overflow helper functions.
c++/test/TestColumnReader.cc Adds regression tests for rejecting negative/overflowing length streams (string/list/map).
c++/test/meson.build Wires the new test source into the Meson test build.
c++/test/CMakeLists.txt Wires the new test source into the CMake test build.
c++/src/Vector.cc Uses checked arithmetic when sizing list/map offset buffers (cap + 1).
c++/src/Utils.hh Introduces reusable checked add/multiply helpers for integral types.
c++/src/MemoryPool.cc Adds checked sizing for DataBuffer allocations and zeroing.
c++/src/DictionaryLoader.cc Guards dictionary blob reads and dictionary offset accumulation against overflow/negative values.
c++/src/ColumnReader.cc Adds overflow/negative-length guards for string direct, list/map length accumulation, union child counts, and double skip sizing.
c++/src/BlockBuffer.hh Avoids potential overflow in getBlockNumber() computation.
c++/src/BlockBuffer.cc Uses checked arithmetic for block buffer size/capacity growth.

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

Comment thread c++/src/BlockBuffer.cc
Comment on lines +56 to +58
uint64_t nextBlockNumber = currentSize_ / blockSize_ + 1;
uint64_t nextSize = 0;
if (multiplyWithOverflow(nextBlockNumber, blockSize_, &nextSize)) {
Comment thread c++/src/ColumnReader.cc
Comment on lines +739 to +747
auto addLength = [&](int64_t value) {
if (value < 0) {
hasNegativeLength = true;
return;
}
size_t length = static_cast<size_t>(value);
size_t nextTotalLength = 0;
bool overflow = addWithOverflow(totalLength, length, &nextTotalLength);
hasLengthOverflow |= overflow;
Comment thread c++/src/MemoryPool.cc
uint64_t checkedBufferSize(uint64_t count) {
uint64_t bytes = 0;
if (multiplyWithOverflow(static_cast<uint64_t>(sizeof(T)), count, &bytes)) {
throw std::length_error("DataBuffer allocation size overflow");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we want to define a orc-specific exception that derives from orc::Exception? arrow-cpp catches all orc::Exception to avoid crashing.

ffacs reacted with thumbs up emoji
Comment thread c++/src/BlockBuffer.cc
if (newBlockPtr != nullptr) {
blocks_.push_back(newBlockPtr);
currentCapacity_ += blockSize_;
try {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why do we need this try-catch block?

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

Reviewers

@wgtmac wgtmac wgtmac left review comments
@dongjoon-hyun dongjoon-hyun dongjoon-hyun left review comments
Copilot code review Copilot
Copilot review effort, defaults to Lite
Applies to this pull request for everyone.Learn more about Copilot code review.
Copilot left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /