Index: third_party/libwebp/dec/buffer.c |
diff --git a/third_party/libwebp/dec/buffer.c b/third_party/libwebp/dec/buffer.c |
index 42feac74c43e08b1fae732374ad4796fc34a44d9..2129312fd6015ff13749f7efce1b5fe3770d79ce 100644 |
--- a/third_party/libwebp/dec/buffer.c |
+++ b/third_party/libwebp/dec/buffer.c |
@@ -33,6 +33,11 @@ static int IsValidColorspace(int webp_csp_mode) { |
return (webp_csp_mode >= MODE_RGB && webp_csp_mode < MODE_LAST); |
} |
+// strictly speaking, the very last (or first, if flipped) row |
+// doesn't require padding. |
+#define MIN_BUFFER_SIZE(WIDTH, HEIGHT, STRIDE) \ |
+ (uint64_t)(STRIDE) * ((HEIGHT) - 1) + (WIDTH) |
+ |
static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) { |
int ok = 1; |
const WEBP_CSP_MODE mode = buffer->colorspace; |
@@ -42,20 +47,22 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) { |
ok = 0; |
} else if (!WebPIsRGBMode(mode)) { // YUV checks |
const WebPYUVABuffer* const buf = &buffer->u.YUVA; |
+ const int uv_width = (width + 1) / 2; |
+ const int uv_height = (height + 1) / 2; |
const int y_stride = abs(buf->y_stride); |
const int u_stride = abs(buf->u_stride); |
const int v_stride = abs(buf->v_stride); |
const int a_stride = abs(buf->a_stride); |
- const uint64_t y_size = (uint64_t)y_stride * height; |
- const uint64_t u_size = (uint64_t)u_stride * ((height + 1) / 2); |
- const uint64_t v_size = (uint64_t)v_stride * ((height + 1) / 2); |
- const uint64_t a_size = (uint64_t)a_stride * height; |
+ const uint64_t y_size = MIN_BUFFER_SIZE(width, height, y_stride); |
+ const uint64_t u_size = MIN_BUFFER_SIZE(uv_width, uv_height, u_stride); |
+ const uint64_t v_size = MIN_BUFFER_SIZE(uv_width, uv_height, v_stride); |
+ const uint64_t a_size = MIN_BUFFER_SIZE(width, height, a_stride); |
ok &= (y_size <= buf->y_size); |
ok &= (u_size <= buf->u_size); |
ok &= (v_size <= buf->v_size); |
ok &= (y_stride >= width); |
- ok &= (u_stride >= (width + 1) / 2); |
- ok &= (v_stride >= (width + 1) / 2); |
+ ok &= (u_stride >= uv_width); |
+ ok &= (v_stride >= uv_width); |
ok &= (buf->y != NULL); |
ok &= (buf->u != NULL); |
ok &= (buf->v != NULL); |
@@ -67,13 +74,14 @@ static VP8StatusCode CheckDecBuffer(const WebPDecBuffer* const buffer) { |
} else { // RGB checks |
const WebPRGBABuffer* const buf = &buffer->u.RGBA; |
const int stride = abs(buf->stride); |
- const uint64_t size = (uint64_t)stride * height; |
+ const uint64_t size = MIN_BUFFER_SIZE(width, height, stride); |
ok &= (size <= buf->size); |
ok &= (stride >= width * kModeBpp[mode]); |
ok &= (buf->rgba != NULL); |
} |
return ok ? VP8_STATUS_OK : VP8_STATUS_INVALID_PARAM; |
} |
+#undef MIN_BUFFER_SIZE |
static VP8StatusCode AllocateBuffer(WebPDecBuffer* const buffer) { |
const int w = buffer->width; |