mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-07-30 16:26:19 +08:00
scale_argb: Harden entry points against large dims
Reject dimensions that overflow the internal fixed-point (dimension << 16) and FixedDiv arithmetic in scale_argb entry points: - ARGBScale and ARGBScaleClip: add the missing src_width and src_height bounds so both are rejected in each direction before reaching ScaleARGB. Add a unit test covering the ARGBScale / ARGBScaleClip paths. Test: libyuv_unittest --gtest_filter=*.ARGBScaleDimensionOverflow Co-authored-by: Timothy Nikkel <tnikkel@mozilla.com> Bug: chromium:531172025 Change-Id: I49577c675725f7d86895ade7eaead826373bd197
This commit is contained in:
parent
b56492e2df
commit
984a8d0a74
@ -697,14 +697,14 @@ static int ScaleARGB(const uint8_t* src,
|
||||
if (clip_x) {
|
||||
int64_t clipf = (int64_t)(clip_x)*dx;
|
||||
x += (clipf & 0xffff);
|
||||
src += (clipf >> 16) * 4;
|
||||
dst += clip_x * 4;
|
||||
src += (ptrdiff_t)(clipf >> 16) * 4;
|
||||
dst += (ptrdiff_t)clip_x * 4;
|
||||
}
|
||||
if (clip_y) {
|
||||
int64_t clipf = (int64_t)(clip_y)*dy;
|
||||
y += (clipf & 0xffff);
|
||||
src += (clipf >> 16) * (ptrdiff_t)src_stride;
|
||||
dst += clip_y * (ptrdiff_t)dst_stride;
|
||||
src += (ptrdiff_t)(clipf >> 16) * src_stride;
|
||||
dst += (ptrdiff_t)clip_y * dst_stride;
|
||||
}
|
||||
|
||||
// Special case for integer step values.
|
||||
@ -779,7 +779,8 @@ int ARGBScaleClip(const uint8_t* src_argb,
|
||||
int clip_width,
|
||||
int clip_height,
|
||||
enum FilterMode filtering) {
|
||||
if (!src_argb || src_width == 0 || src_height == 0 || src_height == INT_MIN ||
|
||||
if (!src_argb || src_width == 0 || src_width > 32768 || src_width < -32768 ||
|
||||
src_height == 0 || src_height > 32768 || src_height < -32768 ||
|
||||
!dst_argb || dst_width <= 0 || dst_height <= 0 || clip_x < 0 ||
|
||||
clip_y < 0 || clip_width > 32768 || clip_height > 32768 ||
|
||||
(clip_x + clip_width) > dst_width ||
|
||||
@ -802,9 +803,9 @@ int ARGBScale(const uint8_t* src_argb,
|
||||
int dst_width,
|
||||
int dst_height,
|
||||
enum FilterMode filtering) {
|
||||
if (!src_argb || src_width == 0 || src_height == 0 || src_height == INT_MIN ||
|
||||
src_width > 32768 || src_height > 32768 || !dst_argb || dst_width <= 0 ||
|
||||
dst_height <= 0) {
|
||||
if (!src_argb || src_width == 0 || src_width > 32768 || src_width < -32768 ||
|
||||
src_height == 0 || src_height > 32768 || src_height < -32768 ||
|
||||
!dst_argb || dst_width <= 0 || dst_height <= 0) {
|
||||
return -1;
|
||||
}
|
||||
return ScaleARGB(src_argb, src_stride_argb, src_width, src_height, dst_argb,
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../unit_test/unit_test.h"
|
||||
@ -597,4 +598,37 @@ TEST_F(LibYUVScaleTest, ARGBTest4x) {
|
||||
free_aligned_buffer_page_end(orig_pixels);
|
||||
}
|
||||
|
||||
// ARGBScale and ARGBScaleClip reach ScaleARGB, which accepts negative width
|
||||
// (horizontal mirror) and height (flip) and takes Abs()/flips to positive
|
||||
// before forming (src_height - 1) << 16 and the step
|
||||
// dx = FixedDiv(Abs(src_width), dst_width) -- both must fit in a signed 16.16
|
||||
// value. Verify oversize width and height are rejected in both directions.
|
||||
TEST_F(LibYUVScaleTest, ARGBScaleDimensionOverflow) {
|
||||
int width = 16;
|
||||
int height = 40000;
|
||||
align_buffer_page_end(src, width * height);
|
||||
align_buffer_page_end(dst, width * height);
|
||||
memset(src, 0, width * height);
|
||||
|
||||
EXPECT_EQ(-1, ARGBScale(src, 16, 1, 32769, dst, 16, 1, 1, kFilterBilinear));
|
||||
EXPECT_EQ(-1, ARGBScale(src, 16, 1, -40000, dst, 16, 1, 1, kFilterBilinear));
|
||||
EXPECT_EQ(-1, ARGBScale(src, 16, 1, 40000, dst, 16, 1, 1, kFilterBilinear));
|
||||
EXPECT_EQ(-1,
|
||||
ARGBScale(src, 40000, 40000, 1, dst, 16, 1, 1, kFilterBilinear));
|
||||
EXPECT_EQ(-1,
|
||||
ARGBScale(src, 40000, -40000, 1, dst, 16, 1, 1, kFilterBilinear));
|
||||
|
||||
EXPECT_EQ(-1, ARGBScaleClip(src, 16, 1, 40000, dst, 16, 1, 1, 0, 0, 1, 1,
|
||||
kFilterBilinear));
|
||||
EXPECT_EQ(-1, ARGBScaleClip(src, 16, 1, -40000, dst, 16, 1, 1, 0, 0, 1, 1,
|
||||
kFilterBilinear));
|
||||
EXPECT_EQ(-1, ARGBScaleClip(src, 40000, 40000, 1, dst, 16, 1, 1, 0, 0, 1, 1,
|
||||
kFilterBilinear));
|
||||
EXPECT_EQ(-1, ARGBScaleClip(src, 40000, -40000, 1, dst, 16, 1, 1, 0, 0, 1, 1,
|
||||
kFilterBilinear));
|
||||
|
||||
free_aligned_buffer_page_end(src);
|
||||
free_aligned_buffer_page_end(dst);
|
||||
}
|
||||
|
||||
} // namespace libyuv
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user