Skip to content

fix(github_reader): derive MAX_BLOB_BYTES from shared parser cap - #148

Open
Tejas5405 wants to merge 2 commits into
IkarusAILabs:mainfrom
Tejas5405:fix/issue-103-oversized-blob-cap
Open

Tejas5405 wants to merge 2 commits into
IkarusAILabs:mainfrom
Tejas5405:fix/issue-103-oversized-blob-cap

Conversation

@Tejas5405

Copy link
Copy Markdown

Fixes #103

Summary

Derive MAX_BLOB_BYTES from MAX_SBOM_BYTES instead of a hardcoded
duplicate so the two caps can never diverge.

Test plan

  • pytest tests/test_bounded_io.py tests/test_github_reader.py — 58 passed
  • ruff check core/github_reader.py — clean

Avoids the per-file blob cap diverging from MAX_SBOM_BYTES. Previously
hardcoded to 50 MB independently, so a change to the parser cap would
silently leave the blob cap stale.

Refs: IkarusAILabs#103

@IkarusAILabs IkarusAILabs left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for picking up #103, and for the clean, focused diff. Deriving the constant instead of duplicating the literal is a good instinct. Two things need to change before this can merge.

1. This PR does not fix #103, but Fixes #103 would close it

MAX_BLOB_BYTES was already 50 MB, the same value as MAX_SBOM_BYTES, so this PR doesn't change behaviour. The part of #103 that is still open (see this comment) is that the per-file cap equals the 50 MB total budget, so a single large file can use up the whole budget.

Reproduced on this branch, with _get_repo_tree stubbed to one 52,428,799-byte package-lock.json followed by five 100-byte requirements.txt files:

selected: ['big/package-lock.json']
reasons:  ['svc0/requirements.txt: repository size cap (52428800 bytes) reached; remaining dependency files not inspected']

All five manifests go uninspected, which is exactly the scenario #103 describes. Merged as is, the issue would auto-close with that bug still there.

Either change the description to Refs #103, or finish #103:

  • Set a per-file cap below the total budget (25 MB is #103's suggestion).
  • Add #103's acceptance test: a tree with one oversized lockfile plus two small manifests. The two manifests are inspected, coverage is PARTIAL with one per-file reason, and the cumulative-cap path still reports its own reason. test_truncated_tree_reports_partial in tests/test_github_reader.py is a good template; stub _get_repo_tree.

2. The existing cap test becomes a tautology

tests/test_bounded_io.py::test_blob_cap_matches_the_parser_cap asserts MAX_BLOB_BYTES == MAX_SBOM_BYTES. With MAX_BLOB_BYTES = MAX_SBOM_BYTES, that compares one object with itself and can never fail, yet the new comment says the relationship is "(enforced by tests)". Please replace it with assertions on the invariants that actually matter:

assert MAX_BLOB_BYTES <= MAX_SBOM_BYTES          # never fetch what no reader will parse
assert MAX_BLOB_BYTES < MAX_DISCOVERED_BYTES     # one file cannot use the whole budget (#103)
assert MAX_BLOB_BYTES <= 100 * 1024 * 1024       # GitHub blobs API limit

A note for CI: this fork's workflows need a maintainer's approval before they run, so a push won't show checks right away.

Inline comments below have the details.

🤖 Review by Claude Code

Comment thread core/github_reader.py
# only to be rejected. Over the cap is an explicit PARTIAL skip, never a silent
# "no dependencies" (F2). Derived from MAX_SBOM_BYTES so the two caps can never
# diverge (enforced by tests).
MAX_BLOB_BYTES = MAX_SBOM_BYTES

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Binding the per-blob cap to the parser cap couples two different limits. If MAX_SBOM_BYTES is ever raised (multi-hundred-MB SBOMs exist), this rises with it, past GitHub's 100 MB blobs-API limit and past the 50 MB MAX_DISCOVERED_BYTES budget, and nothing notices. The pre-download 'exceeds inspection limit' skip would then turn into a fetch failure.

The cap is really the smallest of the three, so it reads more honestly as e.g.

_GITHUB_BLOB_API_LIMIT = 100 * 1024 * 1024
MAX_BLOB_BYTES = min(MAX_SBOM_BYTES, _GITHUB_BLOB_API_LIMIT, MAX_DISCOVERED_BYTES // 2)

(// 2 gives the 25 MB that #103 suggests.)

🤖 Review by Claude Code

Comment thread core/github_reader.py
# is skipped by its tree-declared size before download instead of being fetched
# only to be rejected. Over the cap is an explicit PARTIAL skip, never a silent
# "no dependencies" (F2). Derived from MAX_SBOM_BYTES so the two caps can never
# diverge (enforced by tests).

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

"(enforced by tests)" doesn't hold after this change: test_blob_cap_matches_the_parser_cap now compares the constant with itself (see the review summary). Please update the test to the real invariants, or drop the claim.

🤖 Review by Claude Code

Comment thread core/github_reader.py
MAX_BLOB_BYTES = MAX_SBOM_BYTES
MAX_FILES = 200 # max dependency files to process
MAX_TREE_ENTRIES = 20_000 # bound recursive Git tree expansion before filtering
MAX_DISCOVERED_BYTES = 50 * 1024 * 1024 # 50MB total supported-file budget

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The goal here is that the caps can't diverge, but this is still a separate copy of the same 50 MB literal, and nothing ties it to the per-file cap. Defining the per-file cap relative to this budget (and pinning MAX_BLOB_BYTES < MAX_DISCOVERED_BYTES in a test) would cover the #103 scenario for good.

🤖 Review by Claude Code

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.

github_reader: oversized blob should skip only itself (fix 100MB vs 50MB budget)

2 participants