Commit c213343c8d for aom

commit c213343c8d32bcae729fe09fcba16e1f371cb23b
Author: Wan-Teh Chang <wtc@google.com>
Date:   Fri May 22 16:34:28 2026 -0700

    Check bitstream buffer size in av1_pack_tile_info

    Add the `size` field to struct aom_writer for the buffer size. Add a new
    version of aom_start_encode() called aom_start_encode_with_size() that
    sets the `size` field. The current aom_start_encode() function sets the
    `size` field to 0, which means the buffer size is unknown.

    Call the new aom_start_encode_with_size() function in
    av1_pack_tile_info() so that the aom_stop_encode() call can check the
    tile bitstream buffer size before writing to the tile bitstream buffer.

    Clarify two comments about tile size in av1_pack_tile_info().

    In write_tile_obu(), set pack_bs_params.tile_buf_size because this field
    will be used in av1_pack_tile_info().

    Bug: 42302568
    Bug: oss-fuzz:514006304
    Change-Id: I4e4660255cb9d3d53f96084197ed71d82830266b

diff --git a/aom_dsp/bitwriter.c b/aom_dsp/bitwriter.c
index 36f43da3b6..7fb660dea8 100644
--- a/aom_dsp/bitwriter.c
+++ b/aom_dsp/bitwriter.c
@@ -13,7 +13,14 @@
 #include "aom_dsp/bitwriter.h"

 void aom_start_encode(aom_writer *w, uint8_t *source) {
+  // TODO: bug 42302568 - During the transition period, size=0 means the
+  // buffer size is unknown.
+  aom_start_encode_with_size(w, source, /*size=*/0);
+}
+
+void aom_start_encode_with_size(aom_writer *w, uint8_t *source, size_t size) {
   w->buffer = source;
+  w->size = size;
   w->pos = 0;
   od_ec_enc_init(&w->ec, 62025);
 }
@@ -23,7 +30,9 @@ int aom_stop_encode(aom_writer *w) {
   uint32_t bytes;
   unsigned char *data;
   data = od_ec_enc_done(&w->ec, &bytes);
-  if (!data) {
+  // TODO: bug 42302568 - Remove "w->size != 0 &&" after all aom_start_encode()
+  // calls have been converted to aom_start_encode_with_size().
+  if (!data || (w->size != 0 && bytes > w->size)) {
     od_ec_enc_clear(&w->ec);
     return -1;
   }
diff --git a/aom_dsp/bitwriter.h b/aom_dsp/bitwriter.h
index 5cb26169e9..46da728432 100644
--- a/aom_dsp/bitwriter.h
+++ b/aom_dsp/bitwriter.h
@@ -35,6 +35,7 @@ extern "C" {
 struct aom_writer {
   unsigned int pos;
   uint8_t *buffer;
+  size_t size;
   od_ec_enc ec;
   uint8_t allow_update_cdf;
 };
@@ -60,7 +61,12 @@ static inline void init_token_stats(TOKEN_STATS *token_stats) {
   token_stats->cost = 0;
 }

+// TODO: bug 42302568 - Gradually replace aom_start_encode() calls with
+// aom_start_encode_with_size(). When there are no more aom_start_encode()
+// calls, remove aom_start_encode() and rename aom_start_encode_with_size()
+// back to aom_start_encode().
 void aom_start_encode(aom_writer *w, uint8_t *buffer);
+void aom_start_encode_with_size(aom_writer *w, uint8_t *buffer, size_t size);

 // Returns a negative number on error. Caller must check the return value and
 // handle error.
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 2d6890a678..7cb21bdc65 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3854,11 +3854,16 @@ void av1_pack_tile_info(AV1_COMP *const cpi, ThreadData *const td,

   pack_bs_params->buf.data = pack_bs_params->dst + *total_size;

-  // The last tile of the tile group does not have a header.
+  // The last tile of the tile group does not have a tile_size_minus_1 header.
   if (!pack_bs_params->is_last_tile_in_tg) *total_size += 4;

   // Pack tile data
-  aom_start_encode(&mode_bc, pack_bs_params->dst + *total_size);
+  if (pack_bs_params->tile_buf_size <= *total_size) {
+    aom_internal_error(td->mb.e_mbd.error_info, AOM_CODEC_ERROR,
+                       "Error writing modes");
+  }
+  aom_start_encode_with_size(&mode_bc, pack_bs_params->dst + *total_size,
+                             pack_bs_params->tile_buf_size - *total_size);
   write_modes(cpi, td, &tile_info, &mode_bc, tile_row, tile_col);
   if (aom_stop_encode(&mode_bc) < 0) {
     aom_internal_error(td->mb.e_mbd.error_info, AOM_CODEC_ERROR,
@@ -3871,7 +3876,7 @@ void av1_pack_tile_info(AV1_COMP *const cpi, ThreadData *const td,

   // Write tile size
   if (!pack_bs_params->is_last_tile_in_tg) {
-    // size of this tile
+    // size of this tile minus 1
     mem_put_le32(pack_bs_params->buf.data, tile_size - AV1_MIN_TILE_SIZE_BYTES);
   }
 }
@@ -3953,11 +3958,11 @@ void av1_accumulate_pack_bs_thread_data(AV1_COMP *const cpi,

 // Store information related to each default tile in the OBU header.
 static void write_tile_obu(
-    AV1_COMP *const cpi, uint8_t *const dst, uint32_t *total_size,
-    struct aom_write_bit_buffer *saved_wb, uint8_t obu_extn_header,
-    const FrameHeaderInfo *fh_info, int *const largest_tile_id,
-    unsigned int *max_tile_size, uint32_t *const obu_header_size,
-    uint8_t **tile_data_start) {
+    AV1_COMP *const cpi, uint8_t *const dst, size_t dst_size,
+    uint32_t *total_size, struct aom_write_bit_buffer *saved_wb,
+    uint8_t obu_extn_header, const FrameHeaderInfo *fh_info,
+    int *const largest_tile_id, unsigned int *max_tile_size,
+    uint32_t *const obu_header_size, uint8_t **tile_data_start) {
   AV1_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
   const CommonTileParams *const tiles = &cm->tiles;
@@ -3994,6 +3999,7 @@ static void write_tile_obu(
       // info.
       PackBSParams pack_bs_params;
       pack_bs_params.dst = dst;
+      pack_bs_params.tile_buf_size = dst_size;
       pack_bs_params.curr_tg_hdr_size = 0;
       pack_bs_params.is_last_tile_in_tg = is_last_tile_in_tg;
       pack_bs_params.new_tg = new_tg;
@@ -4149,9 +4155,9 @@ static inline uint32_t pack_tiles_in_tg_obus(
                           &max_tile_size, &obu_header_size, &tile_data_start,
                           num_workers);
   } else {
-    write_tile_obu(cpi, dst, &total_size, saved_wb, obu_extension_header,
-                   fh_info, largest_tile_id, &max_tile_size, &obu_header_size,
-                   &tile_data_start);
+    write_tile_obu(cpi, dst, dst_size, &total_size, saved_wb,
+                   obu_extension_header, fh_info, largest_tile_id,
+                   &max_tile_size, &obu_header_size, &tile_data_start);
   }

   if (num_tiles > 1)