Skip to content

chore(review): adversarial code review of cpp23 wave (PRs #41-#58) - #78

Merged
lusoris merged 1 commit into
masterfrom
chore/cpp23-wave-adversarial-review-20260528
May 28, 2026
Merged

lusoris merged 1 commit into
masterfrom
chore/cpp23-wave-adversarial-review-20260528

Conversation

@lusoris

@lusoris lusoris commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Critical findings

PR File Bug
#43 core/src/opt.cpp string_view::data() passed to strtol/strtod without guaranteed NUL-termination — UB if a substring string_view is ever passed
#48 core/src/dict.cpp strtof (returns float) assigned to double dv — precision loss when high-precision option strings are round-tripped through snprintf("%g", dv)
#54 core/src/model.cpp strlen(model->name) - 5U wraps to SIZE_MAX-4 when name is shorter than 5 chars; downstream calloc(1, SIZE_MAX-4) → heap overflow
#58 core/src/ref.cpp std::make_unique<VmafRef>() allocates via operator new; C callers that call free(ref_ptr) directly (pre-existing pattern) will corrupt the heap

Test plan

  • gh pr diff 41 43 44 45 48 51 54 56 58 -R VMAFx/vmafx reproduces all diffs reviewed.
  • No build or test changes in this PR; pre-commit passes on doc-only files.
  • Affected PRs should each receive a CRITICAL comment (see step 5 below).

Deep-dive deliverables (ADR-0108)

  • Research digest: docs/research/cpp23-wave-adversarial-review-20260528.md
  • No ADR needed: this is a review, not a decision
  • core/AGENTS.md invariant note: C→C++ conversion safety checklist added
  • Reproducer: gh pr diff <N> -R VMAFx/vmafx > /tmp/pr-<N>.diff for N in {41,43,44,45,48,51,54,56,58}
  • changelog.d/changed/cpp23-wave-adversarial-review.md
  • docs/rebase-notes.md entry added
  • docs/state.md row: "cpp23 wave adversarial review (this PR); 4 critical, 2 high, 10 medium"

no rebase impact: read-only review PR; no Netflix upstream surface touched.

🤖 Generated with Claude Code

@lusoris
lusoris enabled auto-merge (squash) May 28, 2026 20:45
lusoris added a commit that referenced this pull request May 28, 2026
…rse_int/parse_double (adversarial review PR #78)

string_view is not guaranteed NUL-terminated; passing sv.data() directly to
strtol/strtod is UB when sv is a substring view. Copy to std::string first.
Fixes the CRITICAL finding flagged in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…ble precision (adversarial review PR #78)

strtof returns float (6-7 significant digits); widening to double loses precision.
One-character fix per CRITICAL finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
… (adversarial review PR #78)

strlen(model->name) - 5U + 1U wraps to a huge size_t when strlen < 5.
Add early-return -EINVAL guard before the subtraction. The suffix-strip
logic is only valid for names longer than 5 chars anyway.
Fixes the CRITICAL finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…in vmaf_ref_close (adversarial review PR #78)

make_unique uses operator new; vmaf_ref_close (C ABI) must use free() to
match the legacy allocator contract and keep ref.c (test harness) and
ref.cpp consistent. Switch to malloc+placement-new and document in ref.h
that vmaf_ref_close is the sole valid deallocator.
Fixes the CRITICAL allocator-mismatch finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Read-only adversarial review of the C to C++23 conversion wave. Found 4
CRITICAL, 2 HIGH, 10 MEDIUM, 3 LOW issues across all 9 PRs. No code
changes; documentation and findings only.

Critical findings:
- PR #48 dict.cpp: strtof (float) assigned to double, precision loss
  on option values causes potential score corruption
- PR #54 model.cpp: strlen(model->name) - 5U unsigned underflow can
  produce SIZE_MAX-4 calloc size, heap overflow
- PR #58 ref.cpp: make_unique/operator-new but C callers may free(),
  allocator mismatch is UB / heap corruption
- PR #43 opt.cpp: string_view::data() passed to strtol without
  guaranteed NUL-termination

All findings documented in docs/research/cpp23-wave-adversarial-review-20260528.md.
Recurring smell pattern added to core/AGENTS.md invariant list.
state.md row added. rebase-notes entry added.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris
lusoris force-pushed the chore/cpp23-wave-adversarial-review-20260528 branch from 6027eb2 to 2779ab5 Compare May 28, 2026 21:35
@lusoris
lusoris merged commit 44f5b25 into master May 28, 2026
18 of 25 checks passed
@lusoris
lusoris deleted the chore/cpp23-wave-adversarial-review-20260528 branch May 28, 2026 21:35
lusoris added a commit that referenced this pull request May 28, 2026
…rse_int/parse_double (adversarial review PR #78)

string_view is not guaranteed NUL-terminated; passing sv.data() directly to
strtol/strtod is UB when sv is a substring view. Copy to std::string first.
Fixes the CRITICAL finding flagged in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…ble precision (adversarial review PR #78)

strtof returns float (6-7 significant digits); widening to double loses precision.
One-character fix per CRITICAL finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
… (adversarial review PR #78)

strlen(model->name) - 5U + 1U wraps to a huge size_t when strlen < 5.
Add early-return -EINVAL guard before the subtraction. The suffix-strip
logic is only valid for names longer than 5 chars anyway.
Fixes the CRITICAL finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…in vmaf_ref_close (adversarial review PR #78)

make_unique uses operator new; vmaf_ref_close (C ABI) must use free() to
match the legacy allocator contract and keep ref.c (test harness) and
ref.cpp consistent. Switch to malloc+placement-new and document in ref.h
that vmaf_ref_close is the sole valid deallocator.
Fixes the CRITICAL allocator-mismatch finding in adversarial review PR #78.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…rse_int/parse_double (adversarial review PR #78) (#43)

string_view is not guaranteed NUL-terminated; passing sv.data() directly to
strtol/strtod is UB when sv is a substring view. Copy to std::string first.
Fixes the CRITICAL finding flagged in adversarial review PR #78.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…ble precision (adversarial review PR #78) (#48)

strtof returns float (6-7 significant digits); widening to double loses precision.
One-character fix per CRITICAL finding in adversarial review PR #78.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
… (adversarial review PR #78) (#54)

strlen(model->name) - 5U + 1U wraps to a huge size_t when strlen < 5.
Add early-return -EINVAL guard before the subtraction. The suffix-strip
logic is only valid for names longer than 5 chars anyway.
Fixes the CRITICAL finding in adversarial review PR #78.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…in vmaf_ref_close (adversarial review PR #78) (#58)

make_unique uses operator new; vmaf_ref_close (C ABI) must use free() to
match the legacy allocator contract and keep ref.c (test harness) and
ref.cpp consistent. Switch to malloc+placement-new and document in ref.h
that vmaf_ref_close is the sole valid deallocator.
Fixes the CRITICAL allocator-mismatch finding in adversarial review PR #78.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris lusoris added this to the 1.0.0 — First release milestone Sep 4, 2026
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