Skip to content

fix(manifest): validate enum fields when parsing manifests - #1034

Open
gty404 wants to merge 2 commits into
apache:mainfrom
gty404:fix/manifest-enum-validation
Open

gty404 wants to merge 2 commits into
apache:mainfrom
gty404:fix/manifest-enum-validation

Conversation

@gty404

@gty404 gty404 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • ManifestReader and ManifestListReader cast raw integers from the file straight into ManifestStatus, DataFile::Content and ManifestContent. An out-of-range value in a manifest then reached switches that end in unreachable(), which is undefined behavior.
  • Validate these fields at parse time through ManifestStatusFromInt, DataFileContentFromInt and a new ManifestContentFromInt, returning InvalidArgument for unknown values.
  • ManifestWriter::WriteEntry now returns an error instead of std::unreachable() for an unknown entry status.

Test plan

  • New tests write manifests / manifest lists with out-of-range data_file.content, status and manifest content (bypassing ManifestWriter) and assert the readers return InvalidArgument
  • New tests fail without the fix and pass with it
  • ctest (all 20 test targets) passes locally

Manifest and manifest list readers cast raw integers from the file
straight into ManifestStatus, DataFile::Content and ManifestContent.
Out-of-range values then reached switches ending in unreachable(),
which is undefined behavior. Validate these fields through the
*FromInt helpers at parse time, and return an error instead of
unreachable() for an unknown status in ManifestWriter::WriteEntry.
@gty404
gty404 force-pushed the fix/manifest-enum-validation branch from 6954c09 to 559066f Compare October 18, 2026 05:40
field_name, required));
ICEBERG_RETURN_UNEXPECTED(
ParseEnumField(DataFileContentFromInt, field_view, manifest_entries,
proj_data_file(&DataFile::content), field_name, required));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The file_format case just below has no else-if-required branch, so a null in that required field silently keeps the default instead of returning MakeNullError the way every other field in this switch does.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks. Fixed in ea36a9c: the kFileFormatFieldId loop now checks required and returns MakeNullError for a null value, same as the other fields in this switch. Added a regression test (RejectsNullRequiredFileFormat) that writes a null file_format via a relaxed write-side schema (bypassing the writer's own non-null enforcement) and asserts the reader rejects it.

gty404 added a commit to gty404/iceberg-cpp that referenced this pull request Oct 20, 2026
ParseDataFile's hand-rolled loop for DataFile::kFileFormatFieldId
skipped the field when null instead of checking `required` and
returning MakeNullError like every other field in the switch,
addressing review feedback on PR apache#1034.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ParseDataFile's hand-rolled loop for DataFile::kFileFormatFieldId
skipped the field when null instead of checking `required` and
returning MakeNullError like every other field in the switch,
addressing review feedback on PR apache#1034.
@gty404
gty404 force-pushed the fix/manifest-enum-validation branch from ea36a9c to ad1bc98 Compare October 20, 2026 02:30

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants