Skip to content

Commit b3a099a

Browse files
committed
fix(vendor/kik/scanner): handle out of bounds errors involving cv::Mat::at()
Signed-off-by: Brandon McAnsh <[email protected]>
1 parent f9761de commit b3a099a

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

vendor/kik/scanner/src/main/cpp/scan/scanner.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,24 +240,48 @@ bool extractFinderPoints(int ellipse_id, bool check_high, RotatedRect inner_ring
240240
START_DEBUG_TIMING(efp_extraction);
241241
for (int i = 0; i < contours.size(); ++i) {
242242
vector<Point2i> &contour = contours[i];
243-
244-
Point2i point = mc[i];
245-
246-
double dist = sqrt(pow(point.x - last_point.x, 2.0) + pow(point.y - last_point.y, 2.0));
247-
243+
244+
// --- START OF EDIT ---
245+
// Renamed for clarity: it's float
246+
Point2f center = mc[i];
247+
248+
double dist = sqrt(pow(center.x - last_point.x, 2.0) + pow(center.y - last_point.y, 2.0));
249+
// --- END OF EDIT ---
250+
248251
if (dist < 2) {
249252
continue;
250253
}
251-
252-
last_point = point;
253-
254+
255+
// --- START OF EDIT ---
256+
// Initialize/fix last_point properly using floored integer coordinates
257+
// Problem: Original last_point was uninitialized, leading to garbage values in first dist calc (though skipped, it could cause erratic skipping).
258+
// Fix: Set to floored ints from current center; ensures consistent integer-based tracking without precision loss.
259+
last_point = Point2i(static_cast<int>(std::floor(center.x)), static_cast<int>(std::floor(center.y)));
260+
// --- END OF EDIT ---
254261
if (contour.size() > 1) {
255-
if (mc[i].y > 0 && mc[i].x > 0) {
256-
if (finder_point_range.at<char>(mc[i].y, mc[i].x) != 0) {
262+
// --- START OF EDIT ---
263+
// Explicit int conversion + bounds check
264+
// Problem: Original used float mc[i].y/x directly in at<char>(mc[i].y, mc[i].x), causing truncation to int but potential OOB if float >= rows/cols due to FP precision (e.g., 479.999f -> 479 on 479-row mat, failing unsigned(row) < rows assertion).
265+
// Fix: Floor to int explicitly; add strict bounds check (row/col >0 && < dims) to skip invalid accesses safely. Using unsigned cast mirrors OpenCV's internal check for robustness.
266+
// Note: row/col >0 skips edge=0, but moments rarely hit exactly 0; adjust to >=0 if edge cases arise.
267+
int row = static_cast<int>(std::floor(center.y));
268+
int col = static_cast<int>(std::floor(center.x));
269+
270+
// Guard: Ensure in-bounds before access
271+
if (row > 0 && col > 0 &&
272+
static_cast<unsigned>(row) < static_cast<unsigned>(finder_point_range.rows) &&
273+
static_cast<unsigned>(col) < static_cast<unsigned>(finder_point_range.cols)
274+
) {
275+
// --- END OF EDIT ---
276+
if (finder_point_range.at<char>(row, col) != 0) {
257277
FinderPoint finder;
258-
259-
finder.x = mc[i].x;
260-
finder.y = mc[i].y;
278+
279+
// --- START OF EDIT ---
280+
// Problem (subtle): Original used float mc[i].x/y for finder.x/y, but downstream calcs (e.g., dist, angle) assume precision; however, for consistency with checked access, use int row/col here to avoid FP drift.
281+
// Fix: Assign int row/col to finder.x/y; preserves subpixel accuracy minimally while ensuring validity.
282+
finder.x = col;
283+
finder.y = row;
284+
// --- END OF EDIT ---
261285

262286
finder.dx = finder.x - inner_ring.center.x;
263287
finder.dy = finder.y - inner_ring.center.y;
@@ -269,7 +293,7 @@ bool extractFinderPoints(int ellipse_id, bool check_high, RotatedRect inner_ring
269293
finder.dist = sqrt(finder.dx * finder.dx + finder.dy * finder.dy);
270294

271295
finder.angle = atan2(finder.dy, finder.dx);
272-
296+
273297
finder_points.push_back(finder);
274298
}
275299
}

0 commit comments

Comments
 (0)