)]}'
{
  "commit": "f3c6b3ab929fad6c653af8b70880c92492c8e681",
  "tree": "ea354c6ba68ff23d0b599b6279623c8b9e039920",
  "parents": [
    "fd0360d985b43599c691d7f18cb954b9b715286f"
  ],
  "author": {
    "name": "Behdad Esfahbod",
    "email": "behdad@behdad.org",
    "time": "Mon May 18 15:11:34 2026 -0600"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon May 18 15:11:34 2026 -0600"
  },
  "message": "[algs] Saturating arithmetic for get_size() on 32-bit (#5988)\n\nOn 32-bit platforms size_t is unsigned int, so the typical\nget_size() computation `min_size + count * static_size`\nsilently wraps when the product exceeds UINT_MAX.  The\ntruncated value then flows into sanitize / serialize as a\nsmall but plausible size, defeating bounds checks.\n\nAdd three helpers in hb-algs.hh:\n\n  hb_unsigned_mul_saturate (a, b, ...)\n  hb_unsigned_add_saturate (a, b, ...)\n  hb_unsigned_mul_add_saturate (a, b, c)   /* a*b + c */\n\nThey saturate to SIZE_MAX on overflow.  Variadic overloads\nleft-fold so 3+ arguments work.  On 64-bit (size_t wider than\nunsigned int), all three reduce to plain a*b / a+b — the\ninputs to size computations are at most unsigned int so the\nresult fits in size_t without overflow.\n\nConvert every get_size() that does arithmetic over variable\ninputs:\n\n  hb-open-type.hh        UnsizedArrayOf, ArrayOf,\n                         HeadlessArrayOf, ArrayOfM1,\n                         sorted-array-with-header, CFFIndex\n  hb-ot-layout-common.hh CmapSubtableFormat-style,\n                         VarRegionList, VarData, MultiVarData,\n                         DeltaSetIndexMapFormat01\n  hb-ot-hdmx-table.hh    DeviceRecord, hdmx\n  hb-ot-cff-common.hh    Charset0, Charset wrapper\n  hb-ot-cff1-table.hh    Encoding, Charset wrapper\n                         (also widened unsigned accumulator\n                         to size_t)\n  hb-ot-os2-table.hh     OS/2 (widened accumulator to size_t)\n  hb-ot-var-common.hh    TupleVariationHeader,\n                         TupleVariationData accumulator\n  hb-ot-var-hvar-table.hh DeltaSetIndexMap\n  hb-vector.hh           hb_vector_t::get_size\n\nWhen saturation kicks in, check_range() and extend_size()\nnaturally reject the resulting value (SIZE_MAX truncated to\nunsigned is UINT_MAX, far past any real blob; extend_size\nalready rejects sizes \u003e\u003d INT_MAX).\n\nAssisted-by: Claude \u003cnoreply@anthropic.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "457b2960e16a00797f1626a69d77198d4c56f920",
      "old_mode": 33188,
      "old_path": "src/hb-algs.hh",
      "new_id": "ebd7e9e6cf29bf4ae21290fa67b2e706bfe949ec",
      "new_mode": 33188,
      "new_path": "src/hb-algs.hh"
    },
    {
      "type": "modify",
      "old_id": "792101664facf50e6a4eb1376316ac2edbeb52bf",
      "old_mode": 33188,
      "old_path": "src/hb-open-type.hh",
      "new_id": "9c7133d46539b3b87892b6c23d5c447f8327fa3b",
      "new_mode": 33188,
      "new_path": "src/hb-open-type.hh"
    },
    {
      "type": "modify",
      "old_id": "1ee1f2874a55a11fa96dd2e34ca4dc6f6e9c45bc",
      "old_mode": 33188,
      "old_path": "src/hb-ot-cff-common.hh",
      "new_id": "72b2b01b39eb3d71ece2832fcaf67d06a30e5048",
      "new_mode": 33188,
      "new_path": "src/hb-ot-cff-common.hh"
    },
    {
      "type": "modify",
      "old_id": "5b2357e7e4313c1fca853ad139f3c12adbebe635",
      "old_mode": 33188,
      "old_path": "src/hb-ot-cff1-table.hh",
      "new_id": "1f66643c191bcf273fa59d3051fab3efb271a795",
      "new_mode": 33188,
      "new_path": "src/hb-ot-cff1-table.hh"
    },
    {
      "type": "modify",
      "old_id": "6ba918e2d7010423f2ac0b9897220e3760600550",
      "old_mode": 33188,
      "old_path": "src/hb-ot-hdmx-table.hh",
      "new_id": "53ce798022d5488c2dfb2424c2c15c79467cf82a",
      "new_mode": 33188,
      "new_path": "src/hb-ot-hdmx-table.hh"
    },
    {
      "type": "modify",
      "old_id": "6d10a4f5938ff2e662b118fff0ef845c147c4f6b",
      "old_mode": 33188,
      "old_path": "src/hb-ot-layout-common.hh",
      "new_id": "f1288efab7f68b55ca99cf57693e8cb50c8fd282",
      "new_mode": 33188,
      "new_path": "src/hb-ot-layout-common.hh"
    },
    {
      "type": "modify",
      "old_id": "1ae0da1267d7d937d6392cbad12619979e176763",
      "old_mode": 33188,
      "old_path": "src/hb-ot-os2-table.hh",
      "new_id": "db8fd4d87958bef62163caa640dd215cdbabf000",
      "new_mode": 33188,
      "new_path": "src/hb-ot-os2-table.hh"
    },
    {
      "type": "modify",
      "old_id": "f8a663b8ae34bc1d1f1f7ad5fb72eed942235372",
      "old_mode": 33188,
      "old_path": "src/hb-ot-var-common.hh",
      "new_id": "0c1c4fc17e3d51943dbd0e6098773adf4b84a68c",
      "new_mode": 33188,
      "new_path": "src/hb-ot-var-common.hh"
    },
    {
      "type": "modify",
      "old_id": "14ccdb7660f368e33cc03b07ef2f5f0b790886c5",
      "old_mode": 33188,
      "old_path": "src/hb-ot-var-hvar-table.hh",
      "new_id": "f7be19e939dca0e5851c75005b6f157112753488",
      "new_mode": 33188,
      "new_path": "src/hb-ot-var-hvar-table.hh"
    },
    {
      "type": "modify",
      "old_id": "7f0b454d2e0a9f0a76bcae1448d6552552c363bf",
      "old_mode": 33188,
      "old_path": "src/hb-vector.hh",
      "new_id": "9f742398c394de82f44c42c86b9ad297e7692e02",
      "new_mode": 33188,
      "new_path": "src/hb-vector.hh"
    }
  ]
}
