Skip to content

Generic safe value-vector conversion (KeyPoint + DMatch)#90

Merged
ViralBShah merged 5 commits into
masterfrom
vs/value-vector-conversion
Jun 5, 2026
Merged

Generic safe value-vector conversion (KeyPoint + DMatch)#90
ViralBShah merged 5 commits into
masterfrom
vs/value-vector-conversion

Conversation

@ViralBShah

Copy link
Copy Markdown
Member

Summary

Generalizes the recently-applied KeyPoint detect→compute fix into a single, extensible conversion for std::vector<value-type>, and closes the identical latent use-after-free in DMatch (match/knnMatch/radiusMatch).

The bug class

The generic cpp_to_julia(StdVector{T}) returns Vector{TDereferenced} whose elements are views into the C++ vector. Once the source std::vector is freed those views dangle (use-after-free), and the Dereferenced element type is invariant-incompatible with the generated signatures (which want Vector{T}). DMatch was safe only because tests called length() without ever dereferencing an element — reading matches[i].distance after a GC would have read freed memory.

Change

Moved the keypoint conversion out of cv_manual_wrap.jl into types_conversion.jl and generalized via a small registry:

  • _copy_cxx_value(::KeyPoint) / _copy_cxx_value(::DMatch) value-copy one element into a fresh, owned object while the source is alive.
  • A for T in (KeyPoint, DMatch) loop emits cpp_to_julia(StdVector{T}) and julia_to_cpp(Array{<:T,1}). Nested Vector{Vector{DMatch}} (knnMatch) is covered via the generic outer path. Adding a type is one tuple entry.

Tests

New test/test_descriptormatcher.jl + additions to test/test_feature2d.jl:

  • DMatch match/knnMatch field reads after GC.gc(true) (use-after-free regression guard).
  • julia_to_cppcpp_to_julia round-trip integrity.
  • KeyPoint GC-stress between detect and compute; _copy_cxx_value field-preservation.

Full suite: 230/230 pass (was 208) against a locally-built OpenCV_jll 4.13.0.

🤖 Generated with Claude Code

ViralBShah and others added 2 commits June 5, 2026 16:48
The generic cpp_to_julia(StdVector{T}) returns a Vector{TDereferenced} whose
elements are views into the C++ vector. Once the source std::vector is freed
those views dangle (use-after-free), and the Dereferenced element type is
invariant-incompatible with the generated signatures (which want Vector{T}).
KeyPoint was patched ad hoc; DMatch (match/knnMatch/radiusMatch) had the same
latent bug, masked only because tests called length() without dereferencing.

Generalize into one place (types_conversion.jl): a _copy_cxx_value registry
that value-copies each element into a fresh, owned object while the source is
alive, with cpp_to_julia(StdVector{T})/julia_to_cpp(Array{<:T,1}) generated for
T in (KeyPoint, DMatch). Nested Vector{Vector{DMatch}} (knnMatch) is covered via
the generic outer path. Adding a type is now one tuple entry.

Tests (test_descriptormatcher.jl + test_feature2d.jl): DMatch match/knnMatch
field reads after GC.gc(true) (use-after-free regression guard), julia_to_cpp
round-trip integrity, KeyPoint GC-stress between detect and compute, and direct
_copy_cxx_value field-preservation checks. 230/230 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
OpenCV_jll pins libcxxwrap_julia_jll = 0.14.7, which requires CxxWrap >= 0.17.4
(registry C/CxxWrap/Compat.toml). The old "0.16, 0.17" left 0.16 admissible —
and 0.16 needs libcxxwrap 0.13, so in any resolve where the JLL does not
transitively force libcxxwrap the solver could pick 0.16 and hit the
'invalid subtyping StdString/CppBasicString' load crash. Drop the dead 0.16.

Verified: clean resolve picks CxxWrap 0.17.5; full suite 230/230. The 'min' CI
job (Julia 1.10) still resolves (0.17.4 supports Julia >= 1.6 and libcxxwrap
0.14.7).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 11.79%. Comparing base (0c3fd1c) to head (f23deaa).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #90      +/-   ##
==========================================
+ Coverage    9.20%   11.79%   +2.59%     
==========================================
  Files          18       18              
  Lines        2086     2594     +508     
==========================================
+ Hits          192      306     +114     
- Misses       1894     2288     +394     

☔ 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.

@ViralBShah ViralBShah merged commit a8d630a into master Jun 5, 2026
10 checks passed
@ViralBShah ViralBShah deleted the vs/value-vector-conversion branch June 5, 2026 21:18
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