Handle non-finite ROI coordinates in CropAndResize#29605
Conversation
…size The CropAndResize CPU kernel computed interpolation indices from ROI box coordinates without accounting for non-finite values. Because every comparison with NaN is false, a NaN coordinate passed the `< 0 || > dim - 1` bounds guard and reached the integer index math, producing an invalid index into the image data. Rewrite both the in_y and in_x bounds guards into the negated-conjunction form `!(coord >= 0 && coord <= dim - 1)`, which is NaN-safe: NaN and inf coordinates now take the extrapolation branch and are filled with extrapolation_value, while behavior for all finite coordinates is unchanged. Also validate crop_size positivity in Compute via ORT_RETURN_IF_NOT, and use SafeInt<int64_t> for the interpolation index computation (allowing the arithmetic-overflow warning suppression pragma to be removed). Add tests for NaN and +/-inf coordinates (bilinear and nearest), finite boundary values (no regression), non-positive crop_size rejection, and an out-of-range batch index. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Tita Wang <titaiwang@microsoft.com>
There was a problem hiding this comment.
Pull request overview
This PR hardens the com.microsoft::CropAndResize CPU contrib op against non-finite ROI coordinates (NaN/±inf) by ensuring they take the extrapolation path instead of reaching integer index computations, and adds input validation for invalid crop sizes. It improves robustness for runtime-provided ROI inputs and reduces the risk of invalid indexing/overflow in the inner interpolation math.
Changes:
- Make ROI bounds checks NaN/inf-safe by using a negated-conjunction guard so non-finite coordinates always extrapolate.
- Reject non-positive
crop_sizevalues early with a clearStatuserror message. - Harden interpolation index arithmetic with
SafeInt<int64_t>and remove the MSVC overflow-warning suppression.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| onnxruntime/contrib_ops/cpu/crop_and_resize.cc | Adds NaN/inf-safe bounds guards, validates crop_size positivity, and uses SafeInt for index/offset arithmetic. |
| onnxruntime/test/contrib_ops/crop_and_resize_op_test.cc | Adds coverage for NaN/±inf ROI extrapolation, finite boundary non-regression, invalid crop_size, and out-of-range batch indices. |
Review — multi-agent pass (readability, correctness, adversarial, spec/deep, integration)Verdict: LGTM. No Critical or Major in-scope blockers. The fix is correct, spec-faithful, and well-tested. Two reviewers independently confirmed the negated-conjunction guard is numerically identical to the old Non-blocking follow-ups (out of scope for this PR)
Minor / nits (optional)
Reviewed by a 5-agent team (Claude / GPT / Gemini families). Findings deduplicated and prioritized by the lead; the float-precision and RoiAlign items were confirmed pre-existing and thus filed as follow-ups rather than blockers. |
|
Can we create a follow-up PR for RoIAlign as well as mentioned in the above comment |
Will do |
Description
The
CropAndResizeCPU contrib op (com.microsoft::CropAndResize) computes bilinear/nearest interpolation indices from the ROI box coordinates. The bounds guards were written asif (in_y < 0 || in_y > height - 1)/if (in_x < 0 || in_x > width - 1). Because every comparison involving a NaN is false, a non-finite (NaN or ±inf) ROI coordinate slipped past both comparisons, skipped the extrapolationcontinue, and reached the integer index computation ((int)floorf(NaN)) with an invalid value.This is a robustness/correctness gap: ROI coordinates are a runtime input, and non-finite values are not handled gracefully.
Fix
if (!(in_y >= 0 && in_y <= height - 1))/if (!(in_x >= 0 && in_x <= width - 1)). This is logically identical for all finite coordinates, but istruefor NaN/±inf, so non-finite coordinates now take the extrapolation branch and are filled withextrapolation_value(matching the documented behavior for out-of-range coordinates).ORT_RETURN_IF_NOT(crop_height > 0 && crop_width > 0, ...)check inComputeso non-positive crop sizes are rejected with a clear error rather than producing degenerate work.SafeInt<int64_t>for the interpolation index computation, which allows the now-unnecessary MSVC 26451 (arithmetic-overflow) suppression pragma to be removed.No behavior change for valid finite ROIs. CPU-only — there is no CUDA
CropAndResizekernel.Tests
Added to
onnxruntime/test/contrib_ops/crop_and_resize_op_test.cc:[0, 1]identity crop and just-outside1.0001) — no regression.crop_size({0, 2}and{-1, 2}) rejected.Run with:
All 10 CropAndResize tests pass (5 new + 5 pre-existing, no regression). An AddressSanitizer build can additionally corroborate the index handling in CI.
Motivation and Context
Handles non-finite ROI coordinates gracefully and makes the CropAndResize index arithmetic robust, consistent with how out-of-range coordinates are already treated (extrapolation).