simp / simp/rubygem-simp-compliance_engine
Malformed check data raises NoMethodError out of mapping?/hiera/fragments instead of being handled
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 2
- Forks
- 1
- Avg merge
- 5d 16h
- Merged PRs (30d)
- 2
Description
0.5.0 added "Handle malformed compliance data gracefully instead of raising" (#111), but four shapes of malformed check data still raise NoMethodError from inside the library. Each is a plausible YAML mistake (wrong indentation, a scalar where a collection belongs).
Reproduced against compliance_engine 1.1.0. Minimal case: one file defining a base profile with a control, plus a second file containing the malformed check; then data.profiles.each_key { |p| data.hiera([p]) }.
| malformed input | raised from |
|---|---|
checks.*.ces is a String |
undefined method 'any?' for an instance of String — data.rb:482 in #mapping? |
checks.*.controls is a String |
private method 'select' called for an instance of String — data.rb:462 in #mapping? |
checks.* value is a scalar |
undefined method 'key?' for an instance of String — component.rb:253 in Component#fragments |
checks.*.settings is a String (on a check that maps to a profile) |
undefined method 'start_with?' for nil — data.rb:389 in #hiera |
The last one is indirect: Check#hiera builds { settings['parameter'] => settings['value'] }, and String#[] returns nil for a non-matching substring, so the parameter name silently becomes nil and blows up later in #hiera rather than at the point the data was wrong.
For contrast, the equivalent malformations on profiles and CEs are all handled gracefully today — profiles.* scalar, profiles.*.ces String, profiles.*.controls String, ce.* scalar, ce.*.controls String, and ce.*.imported_data String all load without raising. It is specifically the check-side paths that are unguarded.
Impact
Any consumer that loads untrusted or in-progress SCE data has to wrap every call in a rescue. It also blocks a fix in scelint: simp/rubygem-simp-scelint#90 covers scelint's own crash on a non-Array ces, but even with that fixed, Scelint::Lint#validate still calls data.hiera and dies here. So the malformed inputs cannot be covered by an end-to-end fixture until this is addressed — they have to be tested against the individual lint methods instead.
Suggested fix
Type-guard the collection accesses in #mapping? (check.ces, check.controls), in Component#fragments (non-Hash fragment), and in Check#hiera (non-Hash settings), logging and skipping rather than raising — consistent with how the profile/CE paths already behave.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in data.rb at #mapping? and #hiera, then inspect component.rb at Component#fragments and the existing profile/CE handling for malformed data. Cover the four listed malformed check shapes with regression tests and confirm they are logged and skipped rather than raising, including through the affected lint paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100