You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@orc.apache.org by do...@apache.org on 2026/07/08 23:14:13 UTC

(orc) branch main updated: ORC-2196: [C++] Validate type tree when creating reader from serialized file tail

This is an automated email from the ASF dual-hosted git repository.

dongjoon-hyun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/orc.git


The following commit(s) were added to refs/heads/main by this push:
     new 11f07f665 ORC-2196: [C++] Validate type tree when creating reader from serialized file tail
11f07f665 is described below

commit 11f07f665eaf64e9c85c60870813096e4fb7effc
Author: Dongjoon Hyun <do...@apache.org>
AuthorDate: Wed Jul 8 16:14:06 2026 -0700

    ORC-2196: [C++] Validate type tree when creating reader from serialized file tail
    
    ### What changes were proposed in this pull request?
    
    This PR aims to validate the ORC type tree in `createReader` when the footer comes from a serialized file tail (`ReaderOptions.setSerializedFileTail`), by calling the existing `checkProtoTypes` in the same way as the file-read path.
    
    ### Why are the changes needed?
    
    The serialized-file-tail branch of `createReader` builds `contents->footer` directly from the parsed `proto::FileTail` without validation. A malformed footer with an out-of-range or back-referencing subtype flows into `convertType`, causing an out-of-bounds read or unbounded recursion (stack overflow) in release builds.
    
    The file-read path already validates via `checkProtoTypes`, and the Java reader validates both tail paths (`OrcTail` and `ReaderImpl`). This closes the remaining C++ parity gap.
    
    ### How was this patch tested?
    
    Pass the CIs with a newly added test case.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Fable 5
    
    Closes #2679 from dongjoon-hyun/ORC-2196.
    
    Authored-by: Dongjoon Hyun <do...@apache.org>
    Signed-off-by: Dongjoon Hyun <do...@apache.org>
---
 c++/src/Reader.cc      |  1 +
 c++/test/TestReader.cc | 29 +++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/c++/src/Reader.cc b/c++/src/Reader.cc
index 68a277fc0..c409576cc 100644
--- a/c++/src/Reader.cc
+++ b/c++/src/Reader.cc
@@ -1646,6 +1646,7 @@ namespace orc {
       }
       contents->postscript = std::make_unique<proto::PostScript>(tail.postscript());
       contents->footer = std::make_unique<proto::Footer>(tail.footer());
+      checkProtoTypes(*contents->footer);
       fileLength = tail.file_length();
       postscriptLength = tail.postscript_length();
     } else {
diff --git a/c++/test/TestReader.cc b/c++/test/TestReader.cc
index fab981339..ee4762a87 100644
--- a/c++/test/TestReader.cc
+++ b/c++/test/TestReader.cc
@@ -1424,4 +1424,33 @@ namespace orc {
         "Invalid compression block size: 8388608");
   }
 
+  /**
+   * Test that createReader validates the type tree when the footer comes
+   * from a serialized file tail, matching the file-read path (ORC-317).
+   */
+  TEST(TestReader, testSerializedFileTailInvalidTypes) {
+    proto::FileTail tail;
+    proto::PostScript* ps = tail.mutable_postscript();
+    ps->set_footer_length(0);
+    ps->set_compression(proto::NONE);
+    ps->set_magic("ORC");
+    proto::Footer* footer = tail.mutable_footer();
+    // Root STRUCT with a subtype that points back to itself (type 0),
+    // which would cause unbounded recursion in convertType if unchecked.
+    proto::Type* rootType = footer->add_types();
+    rootType->set_kind(proto::Type_Kind_STRUCT);
+    rootType->add_subtypes(0);
+    rootType->add_field_names("f1");
+    tail.set_file_length(0);
+    tail.set_postscript_length(0);
+
+    std::string serializedTail;
+    ASSERT_TRUE(tail.SerializeToString(&serializedTail));
+
+    ReaderOptions options;
+    options.setSerializedFileTail(serializedTail);
+    auto stream = std::make_unique<MemoryInputStream>(nullptr, 0);
+    EXPECT_THROW(createReader(std::move(stream), options), ParseError);
+  }
+
 }  // namespace orc