Repository navigation
fix: harden SBOM tools against bad input - #19
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR bundles a set of low-severity hardening fixes across SBOM generation/validation, the compilation-database frontend, and CI, with a new regression test suite (tests/test_low_findings.py) and workflow wiring to ensure these cases stay covered.
Changes:
- Make
gen-sbomwrite CycloneDX/SPDX outputs atomically and deduplicate--srcsonrealpath. - Harden
validate_sbom.pyerror handling and reject non-object top-level JSON. - Improve path/macro handling across
sbom-driver.py,compdb_sbom.py, and CMake SBOM target naming; wire new regression tests into CI.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_low_findings.py |
Adds regression tests covering the bundled low-severity findings. |
share/validate_sbom.py |
Improves robustness: broader read-error handling and top-level JSON type validation. |
share/sbom-driver.py |
Enhances absolute-path scrubbing and guards version-macro extraction. |
share/gen-sbom |
Adds atomic JSON writing and realpath-based --srcs dedup; uses atomic writer for outputs. |
share/frontends/compdb_sbom.py |
Honors -U undefines and restricts sources to --root when provided. |
share/build/sbom.cmake |
Avoids target-name collision on multiple wolfglass_add_sbom() calls. |
.github/workflows/selftest.yml |
Restricts workflow permissions and runs the new low-findings test suite. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+10
to
+22
| from importlib.machinery import SourceFileLoader | ||
|
|
||
| REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||
| SHARE = os.path.join(REPO, "share") | ||
| GEN_SBOM = os.path.join(SHARE, "gen-sbom") | ||
| VALIDATE = os.path.join(SHARE, "validate_sbom.py") | ||
|
|
||
| gs = SourceFileLoader("gen_sbom", GEN_SBOM).load_module() | ||
| drv = SourceFileLoader("sbom_driver", os.path.join(SHARE, "sbom-driver.py") | ||
| ).load_module() | ||
| compdb = SourceFileLoader( | ||
| "compdb_sbom", os.path.join(SHARE, "frontends", "compdb_sbom.py") | ||
| ).load_module() |
Comment on lines
+130
to
+135
| if root_abs: | ||
| real = os.path.realpath(fpath) | ||
| if real != root_abs and not real.startswith(root_abs + os.sep): | ||
| sys.stderr.write( | ||
| f"WARNING: skipping source outside --root: {fpath}\n") | ||
| continue |
Comment on lines
+146
to
+149
| set(_sbom_target sbom) | ||
| if(TARGET sbom) | ||
| set(_sbom_target sbom-${SB_NAME}) | ||
| endif() |
Comment on lines
+44
to
+47
| # Absolute path at the start of a token: a Unix path (/home/...) or a Windows | ||
| # drive path (C:\Users\... or C:/Users/...). Redacted so a host path never | ||
| # leaks into the SBOM regardless of the build host OS. | ||
| _ABS_PATH = re.compile(r'^([A-Za-z]:[\\/]|/)[^ ]*') |
Comment on lines
+112
to
+118
| tmp = f'{path}.tmp' | ||
| try: | ||
| with open(tmp, 'w') as f: | ||
| json.dump(obj, f, indent=2) | ||
| f.write('\n') | ||
| os.replace(tmp, path) | ||
| except OSError: |
sameehj
force-pushed
the
master
branch
4 times, most recently
from
July 24, 2026 14:09
3ab77f9 to
9bdf5b7
Compare
MarkAtwood
force-pushed
the
fix/low-findings-bundle
branch
from
August 13, 2026 01:25
61cf4d2 to
9ce1ea6
Compare
MarkAtwood
force-pushed
the
fix/low-findings-bundle
branch
from
September 29, 2026 01:09
9ce1ea6 to
dfc3dcc
Compare
- gen-sbom: write CycloneDX/SPDX to a temp file in the output directory and rename it into place, so a crash or ENOSPC cannot leave a truncated document. Symlinks, devices and FIFOs (/dev/stdout) are written directly. An existing file keeps its mode; a read-only one is refused. - gen-sbom: dedup --srcs on the normalized absolute path, so foo.c and ./foo.c collapse instead of tripping the duplicate-basename guard. - validate_sbom.py: reject unreadable, non-UTF-8 and non-object JSON input with an error instead of a traceback. - compdb frontend: a later -U cancels an earlier -D, including function-like macros. With --root, skip sources that resolve outside it, since compile_commands.json is untrusted. - sbom-driver: an empty --version-macro returns "" instead of matching the first quoted string in the header. - selftest.yml: permissions: contents: read. Adds tests/test_low_findings.py, wired into selftest.yml.
MarkAtwood
force-pushed
the
fix/low-findings-bundle
branch
from
October 1, 2026 20:54
3c3cf79 to
3c5bf65
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Small fixes across the SBOM tools, each with a regression test in
tests/test_low_findings.py./dev/stdout) are written directly. An existing file keeps its mode; a read-only one is refused.--srcson the normalized absolute path, sofoo.cand./foo.ccollapse instead of tripping the duplicate-basename guard. Distinct names symlinked to one file stay distinct.-Ucancels an earlier-D, including function-like macros. With--root, skips sources that resolve outside it, sincecompile_commands.jsonis untrusted.--root /works.--version-macroreturns""instead of matching the first quoted string in the header.permissions: contents: read, and runs the new tests.