Fix out-of-bounds access in EdgeAwareInterpolator when k exceeds match count - #4201
Fix out-of-bounds access in EdgeAwareInterpolator when k exceeds match count#4201Huxingyu wants to merge 1 commit into
Conversation
…h count The default k=128 exceeds the number of matches sampled on small images (e.g. 48x64 with grid_step 8), leaving -1 sentinel labels in NNlabels that were later read as matches[-1]/transforms[-1], causing a crash. Clamp the neighbors used per call to min(k, match_num) without mutating the user's k, and reject fewer than 3 matches or neighbors with cv::Exception. The RANSAC/KNN passes now operate on the clamped neighbor count, so no -1 sentinel is consumed. Fixes opencv#4195
|
Hi @asmorkalov, this PR fixes #4195 (segfault in This is my first contribution to opencv_contrib, so the CI workflow needs a maintainer to approve it before it will run. Could you approve the workflow when you have a moment? I've already built |
|
Hi @asmorkalov, All CI jobs have now completed. The failures appear to be existing baseline or infrastructure failures rather than regressions from this PR. Most importantly, both test modules affected by this change pass on all four x86 Linux configurations:
The successful macOS, ARM64, and RISC-V jobs provide additional coverage. The red checks are unrelated:
Could you please review the PR and confirm whether these unrelated checks can be treated as baseline failures? If a rerun is preferred, it would probably be more useful after the shared CI issues are repaired. The PR-specific regression tests pass, and the change was also validated locally with ASan. |
Pull Request Checklist
4.x)Summary
Fixes #4195:
calcOpticalFlowSparseToDense(or directEdgeAwareInterpolatoruse) crashes when the configuredkexceeds the actual number of sparse matches.Root cause
EdgeAwareInterpolatorImpl::interpolateallocatesNNlabelsasmatch_num x kand pre-fills it with the-1sentinel. The KNN pass only fills as many entries as it can actually expand, and the RANSAC pass reads exactlykentries per row. Whenk > match_num(e.g. the defaultk=128with the 48x64 /grid_step=8case from the issue, which samples only 48 grid points), the RANSAC pass reads the-1sentinels and dereferencesmatches[-1]/transforms[-1], crashing.Fix
num_neighbors = min(k, match_num)for the current call only; the user'sk(andgetK()) stays unchanged.num_neighbors, so the-1sentinels are never consumed.cv::Exception: fewer than 3 unique matches, ork < 3(the RANSAC affine fit needs 3 points).Tests
DenseOpticalFlow_SparseToDenseFlow.Regression_4195(optflow): default 48x64 input no longer crashes; 8x8 input throwscv::Exception.InterpolatorTest.RejectsTooFewMatches(ximgproc): 0/1/2 matches throwStsBadArg.InterpolatorTest.KExceedsMatchCount(ximgproc):k=128with 5 matches produces valid flow and leavesgetK()==128unchanged.Validation
Built
opencv_test_optflow/opencv_test_ximgproclocally (ASan build) and ran the new regression tests plus the existingInterpolatorTest.MultiThreadReproducibilitysuite — all pass. The standalone repro from the issue no longer crashes under ASan. Data-dependent reference tests requireopencv_extraand run in CI.