Skip to content

fix(validate): reject ptr<CallbackName> as unsupported pointer-to-callback shape - #7

Merged
Sam Gammon (sgammon) merged 2 commits into
mainfrom
detail/bug-fix/fix-validate-reject-ptr-callbackname-as-unsupporte-c6dc0a
Oct 17, 2026
Merged

Sam Gammon (sgammon) merged 2 commits into
mainfrom
detail/bug-fix/fix-validate-reject-ptr-callbackname-as-unsupporte-c6dc0a

Conversation

@detail-app

@detail-app detail-app Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Bug

A function parameter declared param cb type=ptr<Sink>, where Sink is a declared callback signature, passed validation even though it describes a pointer to a function pointer — the same shape already rejected when spelled ptr<fn<Sink>>. Callback names were registered into the shared types set used to validate pointer pointees, so the "unknown pointee" check accepted them. But callbacks are lowered as function-pointer typedefs (typedef void (*Sink)(...)), not struct tags, so the C backend rendered struct Sink * for a struct Sink that was never declared — producing a header that compiles with a warning, fails under -Werror, and is unusable at C call sites without casts.

Struct fields using ptr<Sink> were rejected only by accident of validation ordering (fields validated before callback names were registered), while function parameters validated afterward passed.

Closes #5

Fix

Two changes in Validator.java:

  • type() method: Added a require(!signatures.contains(n.name()), ...) check in the Pointer(Named) branch so a pointer whose Named pointee is a callback signature is rejected with "pointers to callbacks are not supported; use fn<Name>", matching the existing ptr<fn<Sink>> rejection.
  • validate() method: Moved callback-name registration before struct-field validation so both struct fields and function parameters reject ptr<CallbackName> for the same stated reason, rather than struct fields rejecting it only by accident of ordering with a less helpful "unknown pointee" message.

Testing

  • Added two negative test cases to callbacksAndIsolateThreadsAreValidated: ptr<Sink> as a function parameter and ptr<Sink> as a struct field — both must throw IllegalArgumentException.
  • All 152 JVM tests pass (including the 77-case parameterized negative-input suite and golden output comparison).
  • mvn -B verify passes including the JaCoCo coverage gate (≥85% line, ≥70% branch).
  • E2e integration test (tests/e2e.py) passes: generated C header compiles under cc -std=c11 -Wall -Werror, Rust compiles, and FFM round-trip check passes.
  • Manual reproduction confirmed ptr<Sink> throws the expected message in both contexts, while fn<Sink>, ptr<Handle> (opaque), and ptr<ptr<u8>> (nested) continue to work correctly.

Automatic Fixes PRs can be configured here.

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.82%. Comparing base (c7d278e) to head (b4ab1ae).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main       #7      +/-   ##
============================================
+ Coverage     93.77%   93.82%   +0.05%     
- Complexity      656      658       +2     
============================================
  Files            18       18              
  Lines          1895     1895              
  Branches        391      392       +1     
============================================
+ Hits           1777     1778       +1     
  Misses           37       37              
+ Partials         81       80       -1     
Flag Coverage Δ
jvm 93.82% <100.00%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

…eThreadsAreValidated

Add a test case naming a callback 'i64' (a scalar name) to exercise the
require(!isScalarName(signature.name())) branch in Validator.validate,
resolving the codecov/patch partial on the moved callbacks loop.
@sgammon
Sam Gammon (sgammon) merged commit 6faf978 into main Oct 17, 2026
8 of 10 checks passed
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.

[Detail Bug] C bindings: ptr<CallbackName> parameters pass validation and generate malformed C header types

1 participant