Check row allocations before pointer arithmetic

Many conversion helpers allocated a temporary buffer with
align_buffer_64() and then computed sub-row pointers from it before
testing whether the allocation succeeded. align_buffer_64() yields a
NULL base pointer on allocation failure, so these sub-row computations
performed arithmetic on a NULL pointer (undefined behavior) before the
`if (!row) return 1;` guard executed.

Reorder the null check so it immediately follows each allocation,
before any pointer arithmetic into the buffer, matching the correct
convention already used elsewhere (e.g. convert_argb.cc:6465).

Affected sites:
  convert_argb.cc: I444/I422/I420/I210/I010/P410 upsamplers (14 sites)
  convert.cc: two U/V row split allocations
  convert_from_argb.cc: four Y/U/V row split allocations
  planar_functions.cc: ARGBSobel row buffer split

Cast-only sites that merely form (uint16_t*)row without arithmetic are
well-defined on a NULL pointer and were intentionally left unchanged.

R=fbarchard@google.com

Change-Id: Id50912c9d10b021635ad72f0c920f324af1f5a8a
This commit is contained in:
Maximilian Hils 2026-07-22 10:29:20 +00:00
parent b56492e2df
commit 3271bc9d5d
4 changed files with 38 additions and 38 deletions

View File

@ -777,9 +777,9 @@ int I010ToNV12(const uint16_t* src_y,
{
// Allocate a row of uv.
align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
if (!row_u)
return 1;
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
for (y = 0; y < halfheight; ++y) {
Convert16To8Row(src_u, row_u, scale, halfwidth);
@ -1259,9 +1259,9 @@ int I422ToNV21(const uint8_t* src_y,
// Allocate 2 rows of vu.
int awidth = halfwidth * 2;
align_buffer_64(row_vu_0, awidth * 2);
uint8_t* row_vu_1 = row_vu_0 + awidth;
if (!row_vu_0)
return 1;
uint8_t* row_vu_1 = row_vu_0 + awidth;
for (y = 0; y < height - 1; y += 2) {
MergeUVRow(src_v, src_u, row_vu_0, halfwidth);

View File

@ -6728,12 +6728,12 @@ static int I420ToARGBMatrixBilinear(const uint8_t* src_y,
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4);
if (!row)
return 1;
uint8_t* temp_u_1 = row;
uint8_t* temp_u_2 = row + row_size;
uint8_t* temp_v_1 = row + row_size * 2;
uint8_t* temp_v_2 = row + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear(src_u, temp_u_1, width);
ScaleRowUp2_Linear(src_v, temp_v_1, width);
@ -6869,10 +6869,10 @@ static int I422ToARGBMatrixLinear(const uint8_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2);
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
if (!row)
return 1;
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear(src_u, temp_u, width);
@ -7005,12 +7005,12 @@ static int I420ToRGB24MatrixBilinear(const uint8_t* src_y,
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4);
if (!row)
return 1;
uint8_t* temp_u_1 = row;
uint8_t* temp_u_2 = row + row_size;
uint8_t* temp_v_1 = row + row_size * 2;
uint8_t* temp_v_2 = row + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear(src_u, temp_u_1, width);
ScaleRowUp2_Linear(src_v, temp_v_1, width);
@ -7132,12 +7132,12 @@ static int I010ToAR30MatrixBilinear(const uint16_t* src_y,
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4 * sizeof(uint16_t));
if (!row)
return 1;
uint16_t* temp_u_1 = (uint16_t*)(row);
uint16_t* temp_u_2 = (uint16_t*)(row) + row_size;
uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2;
uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear_12(src_u, temp_u_1, width);
ScaleRowUp2_Linear_12(src_v, temp_v_1, width);
@ -7252,10 +7252,10 @@ static int I210ToAR30MatrixLinear(const uint16_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2 * sizeof(uint16_t));
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
if (!row)
return 1;
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear_12(src_u, temp_u, width);
@ -7361,12 +7361,12 @@ static int I010ToARGBMatrixBilinear(const uint16_t* src_y,
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4 * sizeof(uint16_t));
if (!row)
return 1;
uint16_t* temp_u_1 = (uint16_t*)(row);
uint16_t* temp_u_2 = (uint16_t*)(row) + row_size;
uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2;
uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear_12(src_u, temp_u_1, width);
ScaleRowUp2_Linear_12(src_v, temp_v_1, width);
@ -7480,10 +7480,10 @@ static int I210ToARGBMatrixLinear(const uint16_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2 * sizeof(uint16_t));
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
if (!row)
return 1;
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear_12(src_u, temp_u, width);
@ -7668,12 +7668,12 @@ static int I420AlphaToARGBMatrixBilinear(
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4);
if (!row)
return 1;
uint8_t* temp_u_1 = row;
uint8_t* temp_u_2 = row + row_size;
uint8_t* temp_v_1 = row + row_size * 2;
uint8_t* temp_v_2 = row + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear(src_u, temp_u_1, width);
ScaleRowUp2_Linear(src_v, temp_v_1, width);
@ -7880,10 +7880,10 @@ static int I422AlphaToARGBMatrixLinear(const uint8_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2);
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
if (!row)
return 1;
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear(src_u, temp_u, width);
@ -8047,12 +8047,12 @@ static int I010AlphaToARGBMatrixBilinear(
// alloc 4 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 4 * sizeof(uint16_t));
if (!row)
return 1;
uint16_t* temp_u_1 = (uint16_t*)(row);
uint16_t* temp_u_2 = (uint16_t*)(row) + row_size;
uint16_t* temp_v_1 = (uint16_t*)(row) + row_size * 2;
uint16_t* temp_v_2 = (uint16_t*)(row) + row_size * 3;
if (!row)
return 1;
ScaleRowUp2_Linear_12(src_u, temp_u_1, width);
ScaleRowUp2_Linear_12(src_v, temp_v_1, width);
@ -8236,10 +8236,10 @@ static int I210AlphaToARGBMatrixLinear(const uint16_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2 * sizeof(uint16_t));
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
if (!row)
return 1;
uint16_t* temp_u = (uint16_t*)(row);
uint16_t* temp_v = (uint16_t*)(row) + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear(src_u, temp_u, width);
@ -8342,10 +8342,10 @@ static int P010ToARGBMatrixBilinear(const uint16_t* src_y,
// alloc 2 lines temp
const int row_size = (2 * width + 31) & ~31;
align_buffer_64(row, row_size * 2 * sizeof(uint16_t));
uint16_t* temp_uv_1 = (uint16_t*)(row);
uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size;
if (!row)
return 1;
uint16_t* temp_uv_1 = (uint16_t*)(row);
uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size;
Scale2RowUp_Bilinear_16(src_uv, 0, temp_uv_1, row_size, width);
P410ToARGBRow(src_y, temp_uv_1, dst_argb, yuvconstants, width);
@ -8552,10 +8552,10 @@ static int P010ToAR30MatrixBilinear(const uint16_t* src_y,
// alloc 2 lines temp
const int row_size = (2 * width + 31) & ~31;
align_buffer_64(row, row_size * 2 * sizeof(uint16_t));
uint16_t* temp_uv_1 = (uint16_t*)(row);
uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size;
if (!row)
return 1;
uint16_t* temp_uv_1 = (uint16_t*)(row);
uint16_t* temp_uv_2 = (uint16_t*)(row) + row_size;
Scale2RowUp_Bilinear_16(src_uv, 0, temp_uv_1, row_size, width);
P410ToAR30Row(src_y, temp_uv_1, dst_ar30, yuvconstants, width);
@ -8776,10 +8776,10 @@ static int I422ToRGB24MatrixLinear(const uint8_t* src_y,
// alloc 2 lines temp
const int row_size = (width + 31) & ~31;
align_buffer_64(row, row_size * 2);
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
if (!row)
return 1;
uint8_t* temp_u = row;
uint8_t* temp_v = row + row_size;
for (y = 0; y < height; ++y) {
ScaleRowUp2_Linear(src_u, temp_u, width);

View File

@ -555,9 +555,9 @@ int ARGBToNV12Matrix(const uint8_t* src_argb,
// Allocate a rows of uv.
align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
if (!row_u)
return 1;
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
for (y = 0; y < height - 1; y += 2) {
ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width,
@ -770,9 +770,9 @@ int ARGBToNV21Matrix(const uint8_t* src_argb,
// Allocate a rows of uv.
align_buffer_64(row_u, ((halfwidth + 31) & ~31) * 2);
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
if (!row_u)
return 1;
uint8_t* row_v = row_u + ((halfwidth + 31) & ~31);
for (y = 0; y < height - 1; y += 2) {
ARGBToUVMatrixRow(src_argb, src_stride_argb, row_u, row_v, width,
@ -948,10 +948,10 @@ int ARGBToYUY2Matrix(const uint8_t* src_argb,
{
align_buffer_64(row_y, ((width + 63) & ~63) * 2);
uint8_t* row_u = row_y + ((width + 63) & ~63);
uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
if (!row_y)
return 1;
uint8_t* row_u = row_y + ((width + 63) & ~63);
uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
for (y = 0; y < height; ++y) {
ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants);
@ -1061,10 +1061,10 @@ int ARGBToUYVYMatrix(const uint8_t* src_argb,
{
align_buffer_64(row_y, ((width + 63) & ~63) * 2);
uint8_t* row_u = row_y + ((width + 63) & ~63);
uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
if (!row_y)
return 1;
uint8_t* row_u = row_y + ((width + 63) & ~63);
uint8_t* row_v = row_u + ((width + 63) & ~63) / 2;
for (y = 0; y < height; ++y) {
ARGBToUVMatrixRow(src_argb, 0, row_u, row_v, width, constants);

View File

@ -4957,6 +4957,8 @@ static int ARGBSobelize(const uint8_t* src_argb,
// 3 rows with edges before/after.
const int row_size = (width + kEdge + 31) & ~31;
align_buffer_64(rows, row_size * 2 + (kEdge + row_size * 3 + kEdge));
if (!rows)
return 1;
uint8_t* row_sobelx = rows;
uint8_t* row_sobely = rows + row_size;
uint8_t* row_y = rows + row_size * 2;
@ -4965,8 +4967,6 @@ static int ARGBSobelize(const uint8_t* src_argb,
uint8_t* row_y0 = row_y + kEdge;
uint8_t* row_y1 = row_y0 + row_size;
uint8_t* row_y2 = row_y1 + row_size;
if (!rows)
return 1;
ARGBToYJRow(src_argb, row_y0, width);
row_y0[-1] = row_y0[0];
memset(row_y0 + width, row_y0[width - 1], 16); // Extrude 16 for valgrind.