Skip to content

Guard summary keyword lookups#1239

Open
MagnusSletten wants to merge 6 commits into
equinor:mainfrom
MagnusSletten:fix-null-def
Open

Guard summary keyword lookups#1239
MagnusSletten wants to merge 6 commits into
equinor:mainfrom
MagnusSletten:fix-null-def

Conversation

@MagnusSletten

@MagnusSletten MagnusSletten commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Check keyword lookup results before dereferencing them in summary readers. Missing or inconsistent keywords now fail with clear exceptions instead of causing null dereferences.

Approach
Errors found by fuzzing and it's verified that the corresponding error is fixed.

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 hardens summary (SMSPEC/UNSMRY) parsing by adding explicit validation around keyword lookups and data payload types, aiming to replace null-dereferences/UB with clear, actionable failures discovered via fuzzing.

Changes:

  • Add negative/invalid-case tests for malformed SMSPEC/UNSMRY structures (missing keywords, wrong payload types, fixed-width keyword edge case).
  • Add validation checks in SMSPEC/UNSMRY loaders (keyword presence, header entries, payload type/unit presence) to fail fast with exceptions.
  • Update fixed-width keyword string extraction to be width-bounded (no reliance on NUL terminators).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/rd_tests/test_rd_sum.py Adds regression tests for malformed SMSPEC/UNSMRY inputs and fixed-width keyword handling.
lib/resdata/smspec_node.cpp Adds argument/grid-dimension validation when deriving IJK from NUMS for block/completion variables.
lib/resdata/rd_unsmry_loader.cpp Adds PARAMS keyword/type validation and additional file-view entry/header checks.
lib/resdata/rd_smspec.cpp Adds guards for required SMSPEC keywords and payload validation (e.g., STARTDAT int payload, TIME unit).
lib/resdata/rd_file_view.cpp Adds a guard for missing keyword entries during indexed keyword loading.
lib/include/resdata/rd_kw.hpp Changes stripped-string extraction to use fixed-width reads (string_view) instead of relying on NUL termination.

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

Comment thread lib/resdata/rd_unsmry_loader.cpp Outdated
Comment thread lib/include/resdata/rd_kw.hpp
Comment thread lib/resdata/rd_smspec.cpp Outdated
Comment thread lib/resdata/smspec_node.cpp Outdated
Check keyword lookup results before dereferencing them in summary readers.
Missing or inconsistent keywords now fail with clear exceptions instead of
causing null dereferences.

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

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

Comment thread lib/resdata/smspec_node.cpp
Comment thread lib/include/resdata/rd_kw.hpp Outdated

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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread lib/include/resdata/rd_kw.hpp Outdated
@MagnusSletten MagnusSletten marked this pull request as ready for review July 10, 2026 05:48
Comment thread lib/resdata/rd_smspec.cpp
const rd_kw_type *intehead =
rd_file_iget_named_kw(header.get(), INTEHEAD_KW, 0);
if (intehead == NULL)
throw std::invalid_argument(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This seems like a logic bug in how rd_file handles kw. It shouldn't ever say it "has" a keyword and then return NULL. Maybe we could have a closer look at how this happened if you still have the file that created this scenario?

Comment thread tests/rd_tests/test_rd_sum.py Outdated
Comment thread tests/rd_tests/test_rd_sum.py Outdated
Comment thread tests/rd_tests/test_rd_sum.py Outdated
Comment thread tests/rd_tests/test_rd_sum.py Outdated
static_cast<const char *>(rd_kw_iget_ptr(kw, index)));
const char *raw = static_cast<const char *>(rd_kw_iget_ptr(kw, index));
const size_t width = rd_type_get_sizeof_iotype(rd_kw_get_data_type(kw));
size_t len = 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could be nice with some unit-tests for this.

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.

Added a few now

@eivindjahren eivindjahren left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Had some small comments that are easily fixed :)

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.

3 participants