)]}'
{
  "commit": "e925361117e4270b1e3a0e5103db506d87a4aa63",
  "tree": "0792e9f486f9bec4c5d1067cc2135f0cbb4134b4",
  "parents": [
    "849e1cbf91afbb70615f0978b336cf8a8f33733e"
  ],
  "author": {
    "name": "m00dy",
    "email": "professor.moody@pm.me",
    "time": "Wed Nov 04 12:17:30 2026 -0800"
  },
  "committer": {
    "name": "Copybara-Service",
    "email": "copybara-worker@google.com",
    "time": "Wed Nov 04 12:32:12 2026 -0800"
  },
  "message": "fix(upb): guard array, map reserve, and extension registry against size/shift overflow (#30787)\n\n## Summary\n\nThis PR adds overflow and shift-bounds checks across `upb/message` and `upb/mini_table/extension_registry.c`:\n\n1. **`_upb_Array_NewMaybeAllowSlow` and `_upb_Array_TryFastRealloc` (`upb/message/internal/array.h`)**:\n   - In `_upb_Array_NewMaybeAllowSlow`, `const size_t elem_bytes \u003d init_capacity \u003c\u003c elem_size_lg2;` and the arena pool lookup previously ran *before* checking whether `init_capacity` overflows `size_t` when shifted by `elem_size_lg2`. If `init_capacity \u003d (SIZE_MAX \u003e\u003e elem_size_lg2) + 1` and a 16-byte recycled pool block is present on the arena, `elem_bytes` wraps to `0`, `pool_bytes` becomes `16`, and `_upb_Array_New` returns a non-`NULL` under-sized array (`capacity \u003d 16 \u003e\u003e elem_size_lg2`, e.g. `2` for 8-byte elements) instead of failing with `NULL`. Move and tighten the `init_capacity` upper-bound check (`init_capacity \u003e (max_bytes - array_size) \u003e\u003e elem_size_lg2`) before the shift and pool lookup.\n   - In `_upb_Array_TryFastRealloc`, guard `capacity \u003e max_bytes \u003e\u003e elem_size_lg2` before `capacity \u003c\u003c elem_size_lg2`.\n\n2. **`upb_Array_Insert` (`upb/message/array.c`)**:\n   - `upb_Array_Insert` checked `upb_AddOverflow(arr-\u003eUPB_PRIVATE(size), count, \u0026new_size)` only via `UPB_ASSERT(ok)`, which is compiled out under `NDEBUG`. In release builds on a non-empty array, `upb_Array_Insert(arr, 0, SIZE_MAX, arena)` wraps `new_size` below `arr-\u003eUPB_PRIVATE(size)`, passes `_upb_Array_ResizeUninitialized`, and calls `upb_Array_Move` with `i + count` out of bounds. Return `false` when `!ok` (matching `upb_Array_AppendAll`).\n\n3. **`_upb_Map_Reserve` (`upb/message/map.c`)**:\n   - Guard against `size` addition overflow and `size_lg2 \u003e\u003d 32` before evaluating `(size_t)1 \u003c\u003c size_lg2` (which triggers undefined shift behavior when `size_lg2 \u003e\u003d sizeof(size_t) * CHAR_BIT`).\n\n4. **`upb_ExtensionRegistry_AddArray` (`upb/mini_table/extension_registry.c`) and `_upb_Message_Copy` (`upb/message/copy.c`)**:\n   - Guard `count * sizeof(*e)` and pointer addition wraparound in `upb_ExtensionRegistry_AddArray` before `UPB_PTRADD(e, count)`.\n   - Guard `mini_table-\u003eUPB_PRIVATE(size) \u003c sizeof(upb_Message)` before subtracting `sizeof(upb_Message)` in `_upb_Message_Copy`.\n\n## Test Plan\n\n- Added `MessageTest.ArrayMapAndExtensionRegistryOverflow` in `upb/message/test.cc` covering `_upb_Array_New` with a seeded 16-byte arena pool block, `_upb_Array_TryFastRealloc`, `upb_Array_Insert` (`NDEBUG`), `upb_Map_Reserve`, and `upb_ExtensionRegistry_AddArray`.\n- Verified with Bazel 8.6.0 and clang 21.1.8 on Linux x86_64: `bazel test //upb/...` (48 test targets) passes under `-c opt`, the default fastbuild configuration, and `--config\u003dasan --config\u003dubsan`, with `//upb/message:test` run 3 times in each. On unpatched `main` the new test fails in all three configurations.\n\nRelated: the `_upb_Array_NewMaybeAllowSlow` bound builds on the check added by #27712. That check runs only on the pool-miss path, after `elem_bytes \u003d init_capacity \u003c\u003c elem_size_lg2` has already been computed and used for the pool lookup; this change moves the same bound ahead of the shift and the pool lookup and also reserves `UPB_MALLOC_ALIGN - 1` and the ASan guard size. The other sites (`upb_Array_Insert`, `_upb_Array_TryFastRealloc`, `_upb_Map_Reserve`, `upb_ExtensionRegistry_AddArray`, `_upb_Message_Copy`) are not touched by #27712 or by the earlier `_upb_Array_Realloc` PRs (#26373, #26534, #27568).\n\nCloses #30787\n\nCOPYBARA_INTEGRATE_REVIEW\u003dhttps://github.com/protocolbuffers/protobuf/pull/30787 from professor-moody:fix-upb-array-map-extreg-overflow-guards 5c6cb3354601b6b1433abba09944ecaaffae6aa6\nFUTURE_COPYBARA_INTEGRATE_REVIEW\u003dhttps://github.com/protocolbuffers/protobuf/pull/30787 from professor-moody:fix-upb-array-map-extreg-overflow-guards 5c6cb3354601b6b1433abba09944ecaaffae6aa6\nPiperOrigin-RevId: 1014041046\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "a4369af925003ca0204e194207f73cbe22e0c547",
      "old_mode": 33188,
      "old_path": "upb/message/array.c",
      "new_id": "61b78103acbc8f9283c8484525f649e309b00343",
      "new_mode": 33188,
      "new_path": "upb/message/array.c"
    },
    {
      "type": "modify",
      "old_id": "dda2961890cc65c4782b6445a769df578a118c09",
      "old_mode": 33188,
      "old_path": "upb/message/copy.c",
      "new_id": "a9b691eaf5a909d595d821bdb9e1ef44a64379d8",
      "new_mode": 33188,
      "new_path": "upb/message/copy.c"
    },
    {
      "type": "modify",
      "old_id": "61311a1303e91640adc04d83288bd84ebd68ec7b",
      "old_mode": 33188,
      "old_path": "upb/message/internal/array.h",
      "new_id": "daf0f46ab590053cbb5de9662f67a46da42fb846",
      "new_mode": 33188,
      "new_path": "upb/message/internal/array.h"
    },
    {
      "type": "modify",
      "old_id": "e01dce67d216875d692aea5aac3bd520ff52c21d",
      "old_mode": 33188,
      "old_path": "upb/message/map.c",
      "new_id": "379e483d900c1276a695da447e13f3307b9725d4",
      "new_mode": 33188,
      "new_path": "upb/message/map.c"
    },
    {
      "type": "modify",
      "old_id": "ef34026d7a6470d21c17e336090d6621b7052c2a",
      "old_mode": 33188,
      "old_path": "upb/message/test.cc",
      "new_id": "778b6a816c6990e2490af20199617b12e0540925",
      "new_mode": 33188,
      "new_path": "upb/message/test.cc"
    },
    {
      "type": "modify",
      "old_id": "a2f23ea167c155bec3e2dbca99256014f0ff36c5",
      "old_mode": 33188,
      "old_path": "upb/mini_table/extension_registry.c",
      "new_id": "b42bf1a2c8534f331277f75bd147e651f154ec09",
      "new_mode": 33188,
      "new_path": "upb/mini_table/extension_registry.c"
    }
  ]
}
