-
Notifications
You must be signed in to change notification settings - Fork 4.3k
GH-51238: [C++][Python][Parquet] Limit schema nesting depth when reading #51239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,10 @@ constexpr int32_t kDefaultThriftStringSizeLimit = 100 * 1000 * 1000; | |
| // kDefaultStringSizeLimit. | ||
| constexpr int32_t kDefaultThriftContainerSizeLimit = 1000 * 1000; | ||
|
|
||
| // Maximum schema nesting depth. This default value is conservatively small as | ||
| // some systems may not set a very large stack size. | ||
| constexpr int32_t kDefaultSchemaDepthLimit = 100; | ||
|
|
||
| // PARQUET-978: Minimize footer reads by reading 64 KB from the end of the file | ||
| constexpr int64_t kDefaultFooterReadSize = 64 * 1024; | ||
|
|
||
|
|
@@ -121,6 +125,15 @@ class PARQUET_EXPORT ReaderProperties { | |
| thrift_container_size_limit_ = size; | ||
| } | ||
|
|
||
| /// \brief Return the schema nesting depth limit. | ||
| /// | ||
| /// This limit helps prevent denial of service through excessive recursion | ||
| /// (stack overflow) when reconstructing the Parquet schema from the file metadata. | ||
| /// The default value is conservative enough for most use cases. | ||
| int32_t schema_depth_limit() const { return schema_depth_limit_; } | ||
| /// Set the schema nesting depth limit. | ||
| void set_schema_depth_limit(int32_t size) { schema_depth_limit_ = size; } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was thinking if we need to reject a negative value here but it seems that it will safely throw later so I'm fine to leave it simple here.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have any conventions regarding the use of
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use signed integers in most public APIs, we should probably not deviate here. |
||
|
|
||
| /// Set the decryption properties. | ||
| void file_decryption_properties(std::shared_ptr<FileDecryptionProperties> decryption) { | ||
| file_decryption_properties_ = std::move(decryption); | ||
|
|
@@ -146,6 +159,7 @@ class PARQUET_EXPORT ReaderProperties { | |
| int64_t buffer_size_ = kDefaultBufferSize; | ||
| int32_t thrift_string_size_limit_ = kDefaultThriftStringSizeLimit; | ||
| int32_t thrift_container_size_limit_ = kDefaultThriftContainerSizeLimit; | ||
| int32_t schema_depth_limit_ = kDefaultSchemaDepthLimit; | ||
| bool buffered_stream_enabled_ = false; | ||
| bool page_checksum_verification_ = false; | ||
| // Used with a RecordReader. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a drive-by fix for an unrelated buglet.