Skip to content

[fix] bound the script-controlled allocations in file, random, and choices - #172

Merged
vt128 merged 1 commit into
masterfrom
fix/bound-script-controlled-allocations
Jul 13, 2026
Merged

[fix] bound the script-controlled allocations in file, random, and choices#172
vt128 merged 1 commit into
masterfrom
fix/bound-script-controlled-allocations

Conversation

@vt128

@vt128 vt128 commented Jul 13, 2026

Copy link
Copy Markdown
Member

What

Several places let a script size a make() directly, with no upper bound — an OOM is a runtime fatal, so the run/call recover cannot turn it into an error.

  • file.tail_lines(name, n) allocated its ring buffer as make([]string, n, n) before reading a line, so tail_lines(path, 10**12) OOM-killed the host however small the file. head_lines grew incrementally and had no such flaw — the asymmetry was the bug. The ring now grows to the lines actually read, so a huge n just means "every line". The entry point stops swallowing an out-of-int64 n and clamps to the platform int max before narrowing (no 32-bit wrap).
  • random.randbytes/randstr/randb32 passed n straight to make() after only a Sign() <= 0 check, and big.Int.Int64() is undefined past int64 (negative → make panics, wrapped → silently empty, in-range-but-huge → OOM). A shared randLen() rejects a value that does not fit an int64 and caps the length at 1 MiB. randb32's separator is compared as int64 before narrowing.
  • random.choices(pop, k=…) sized make([]starlark.Value, k) from k with no bound; k is now capped the same way, and the weights/cum_weights length is checked against the population before materializing a []float64.

Behavior change

randbytes/randstr/randb32/choices error on a length/k over 1 MiB instead of attempting the allocation. READMEs state the new bounds.

Tests

Over-cap and beyond-int64 cases for each function; a huge tail_lines returns every line; at-cap still works. Full -race/vet/gofmt/doc-coverage/Docker go1.19 clean.

…oices

Several places let a script size a make() directly, with no upper bound — an
OOM is a runtime fatal, so the run/call recover cannot even turn it into an
error:

- file.tail_lines(name, n) allocated its ring buffer as make([]string, n, n)
  before reading a line, so tail_lines(path, 10**12) OOM-killed the host
  however small the file. head_lines grew incrementally and had no such flaw —
  the asymmetry was the bug. The ring now grows to the lines actually read, so
  a huge n simply means "every line". The entry point stops swallowing an
  out-of-int64 n (Int64() is undefined there) and clamps n to the platform int
  max before narrowing, so a value past a 32-bit int no longer wraps.

- random.randbytes/randstr/randb32 passed n straight to make() after only a
  Sign() <= 0 check, and big.Int.Int64() is undefined past int64 (negative ->
  make panics, wrapped -> silently empty, in-range-but-huge -> OOM). A shared
  randLen() now rejects a value that does not fit an int64 and caps the length
  at 1 MiB. randb32's separator is compared as int64 before narrowing.

- random.choices(pop, k=...) sized make([]starlark.Value, k) from k with no
  bound; k is now capped the same way.

READMEs state the new bounds (the honest-boundary rule).

Behavior change: randbytes/randstr/randb32/choices error on a length/k over
1 MiB instead of attempting the allocation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codacy-production

codacy-production Bot commented Jul 13, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 13 complexity · 5 duplication

Metric Results
Complexity 13
Duplication 5

View in Codacy

🟢 Coverage 96.00% diff coverage · 0.00% coverage variation

Metric Results
Coverage variation 0.00% coverage variation (-1.00%)
Diff coverage 96.00% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (5d4c419) Report Missing Report Missing Report Missing
Head commit (db1de73) 7809 (+36) 7390 (+34) 94.63% (0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#172) 50 48 96.00%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

1 Codacy didn't receive coverage data for the commit, or there was an error processing the received data. Check your integration for errors and validate that your coverage setup is correct.

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.73684% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.43%. Comparing base (5d4c419) to head (db1de73).

Files with missing lines Patch % Lines
lib/file/file.go 60.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #172      +/-   ##
==========================================
+ Coverage   93.42%   93.43%   +0.01%     
==========================================
  Files          50       50              
  Lines        6222     6248      +26     
==========================================
+ Hits         5813     5838      +25     
  Misses        261      261              
- Partials      148      149       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vt128
vt128 merged commit 1b0a450 into master Jul 13, 2026
21 checks passed
@vt128
vt128 deleted the fix/bound-script-controlled-allocations branch July 13, 2026 01:27
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.

1 participant