From ca43934acfee34feb2d8d7245c2abb812f63802b Mon Sep 17 00:00:00 2001 From: Pedro Ferreira Date: Fri, 2 Oct 2026 13:15:14 +0000 Subject: [PATCH] More missing bound checks --- c++/src/Reader.cc | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/c++/src/Reader.cc b/c++/src/Reader.cc index a64b769273..58b8534dcb 100644 --- a/c++/src/Reader.cc +++ b/c++/src/Reader.cc @@ -523,7 +523,14 @@ namespace orc { for (int i = 0; i < currentStripeFooter_.streams_size(); ++i) { const proto::Stream& pbStream = currentStripeFooter_.streams(i); uint64_t colId = pbStream.column(); - if (selectedColumns_[colId] && pbStream.has_kind() && + if (pbStream.has_kind() && colId >= selectedColumns_.size()) { + std::stringstream msg; + msg << "Malformed stream meta at stream index " << i << " in stripe " << currentStripe_ + << ": column=" << colId << " is out of range, the file has " << selectedColumns_.size() + << " columns"; + throw ParseError(msg.str()); + } + if (pbStream.has_kind() && selectedColumns_[colId] && (pbStream.kind() == proto::Stream_Kind_ROW_INDEX || pbStream.kind() == proto::Stream_Kind_BLOOM_FILTER_UTF8)) { std::unique_ptr inStream; @@ -556,6 +563,14 @@ namespace orc { if (!parseProtobufFromStream(&pbBFIndex, inStream.get())) { throw ParseError("Failed to parse bloom filter index"); } + if (colId >= static_cast(currentStripeFooter_.columns_size())) { + std::stringstream msg; + msg << "Malformed bloom filter stream at stream index " << i << " in stripe " + << currentStripe_ << ": column=" << colId + << " has no column encoding, the stripe has " << currentStripeFooter_.columns_size() + << " column encodings"; + throw ParseError(msg.str()); + } BloomFilterIndex bfIndex; for (int j = 0; j < pbBFIndex.bloom_filter_size(); j++) { bfIndex.entries.push_back(BloomFilterUTF8Utils::deserialize( @@ -835,6 +850,13 @@ namespace orc { } int num_entries = rowIndex.entry_size(); size_t column = static_cast(stream.column()); + if (column >= indexStats->size()) { + std::stringstream msg; + msg << "Malformed RowIndex stream meta at stream index " << i << " in stripe " + << stripeIndex << ": column=" << column << " is out of range, the stripe has " + << indexStats->size() << " column statistics"; + throw ParseError(msg.str()); + } for (int j = 0; j < num_entries; j++) { const proto::RowIndexEntry& entry = rowIndex.entry(j); (*indexStats)[column].push_back(entry.statistics()); @@ -1733,6 +1755,14 @@ namespace orc { if (!parseProtobufFromStream(&pbBFIndex, pbStream.get())) { throw ParseError("Failed to parse BloomFilterIndex"); } + if (stream.column() >= static_cast(currentStripeFooter.columns_size())) { + std::stringstream msg; + msg << "Malformed bloom filter stream at stream index " << i << " in stripe " + << stripeIndex << ": column=" << stream.column() + << " has no column encoding, the stripe has " << currentStripeFooter.columns_size() + << " column encodings"; + throw ParseError(msg.str()); + } BloomFilterIndex bfIndex; for (int j = 0; j < pbBFIndex.bloom_filter_size(); j++) {