fix(kpm): bound matcher image ids and the reference image count - #74
Conversation
Two review findings on #73 (pre-existing, widened by #71's per-page results): - kpmSetRefDataSet() never clears the FREAK matcher, so when a reference set is replaced by a smaller one its extra images stay in the matcher and are still matched. Their ids keep old pageIndices entries that can point past the new, smaller result[]. Record how many images the current set registered (dbImageNum) and ignore, with an error, any match at or above it, or mapping outside result[]. Clearing the matcher on reload is the proper fix and belongs to the non-idempotent kpmSetRefDataSet (webarkit/jsartoolkitNFT#612). - pageIDs[] and pageIndices[] hold DB_IMAGE_MAX (1024) entries, one per registered image, but nothing bounded the image count. Reject a dataset with more images than that before changing any state. Built and tested through jsartoolkitNFT (the only build that compiles lib/SRC/KPM): detection, multi-marker and marker-limit suites, 82/82. Refs webarkit/jsartoolkitNFT#635, webarkit/jsartoolkitNFT#612 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Summary by QodoBound KPM reference images and stale matcher IDs
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1.
|
Review findings on #74: - Reusing the matcher across kpmSetRefDataSet() calls kept every keyframe it held. An id registered again was refused as a duplicate (the old keyframe stayed) while the facade still replaced its 3D points, so pose estimation could pair old matches with a new, shorter point list and index past it. The dbImageNum check cannot see this: the id is in range. Recreate the matcher before registering the new set; it carries no configuration beyond construction, so the new instance is equivalent. The id and page-position checks in kpmMatching stay as invariant guards. - The DB_IMAGE_MAX preflight summed imageNum values in a signed int before comparing, so a corrupt dataset could overflow past the check. Check each count against the room left before adding it, and reject negative counts. Built and tested through jsartoolkitNFT: detection, multi-marker and marker-limit Vitest suites 82/82; Node example detects 10/10. Refs webarkit/jsartoolkitNFT#612, webarkit/jsartoolkitNFT#635 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Addresses the two Qodo findings on the 0.9.0 release sync #73. Both weaknesses predate #71, but #71 widened them by processing every match instead of only the best one. The fix lands here on
dev, and #73 (dev→master) picks it up automatically.1. Stale matcher images after reloading a smaller reference set
kpmSetRefDataSet()never clears the FREAK matcher, anddb_idrestarts at 0, so a replaced reference set's extra images stay in the matcher and are still matched. Their ids keep oldpageIndicesentries that can point past the new, smallerresult[].KpmHandlegainsdbImageNum: the number of images the current reference set registered. The handle isarMallocClear-ed, so it starts at 0.kpmMatchingignores, with anARLOGe, any match whose id is>= dbImageNum, or whose page position falls outsideresult[].This removes the out-of-bounds access. It does not make reloading correct: ids below the new count still refer to the previous set's features. Clearing the matcher on reload is the proper fix, and it belongs to the non-idempotent
kpmSetRefDataSet(webarkit/jsartoolkitNFT#612).2. No bound on the reference image count
pageIDs[]andpageIndices[]holdDB_IMAGE_MAX(1024) entries, one per registered image (pages × scales), but nothing checked the total.kpmSetRefDataSet()now counts the images first, and rejects the dataset with an error before changing any state.Testing
WebARKitLib's CI builds the
WebARKit/tracker, notlib/SRC/KPM. So this was built and tested through jsartoolkitNFT (Docker, emsdk 4.0.17), which compiles this code into its WASM. There were no warnings in the changed files, and thedetection,multi-markerandmarker-limitVitest suites pass 82/82.Refs webarkit/jsartoolkitNFT#635, webarkit/jsartoolkitNFT#612
🤖 Generated with Claude Code