)]}'
{
  "commit": "f9fee4fc688aca367e46512f9a6fb48c94dcb6f3",
  "tree": "acf7a0ffa9ca886b9394838884739e37d1370dc2",
  "parents": [
    "5557d2bb82611510b9903acaf799515c37f2abd9"
  ],
  "author": {
    "name": "jdymitarai",
    "email": "100186003+jdymitarai@users.noreply.github.com",
    "time": "Sun Sep 13 23:49:00 2026 +0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Sun Sep 13 15:49:00 2026 +0000"
  },
  "message": "guard non-positive requested digits in DoubleToAscii and BignumDtoa (#318)\n\nFollowing the hardening of `DigitGenCounted` (#313),\n`GenerateCountedDigits` (#314), and `FastFixedDtoa` (#315) against\nnon-positive/negative counts, entry points and bignum utilities still\nhad edge cases in release builds (`-DNDEBUG`):\n\n1. **`DoubleToStringConverter::DoubleToAscii`**:\n- `DoubleToAscii` checked `if (mode \u003d\u003d PRECISION \u0026\u0026 requested_digits \u003d\u003d\n0)` to return an empty representation (`*length \u003d 0`, `*point \u003d 0`).\n- When called with `requested_digits \u003c 0` in release builds (where\n`DOUBLE_CONVERSION_ASSERT` is compiled out), this check failed.\n`FastDtoa` returned false (#313), and execution proceeded to\n`BignumDtoa`, setting `*length \u003d 0` (#314) but leaving `*point` at an\nunreset, non-zero value, after doing redundant bignum work.\n- For `mode \u003d\u003d FIXED` with `requested_digits \u003c 0`, `DoubleToAscii` fell\nthrough to `BignumDtoa`, where `BignumToFixed` could emit truncated\ninteger digits into `buffer` when `(*decimal_point) + requested_digits \u003e\n0`.\n\n2. **`BignumDtoa`**:\n- For `mode \u003d\u003d BIGNUM_DTOA_PRECISION \u0026\u0026 requested_digits \u003c\u003d 0` or `mode\n\u003d\u003d BIGNUM_DTOA_FIXED \u0026\u0026 requested_digits \u003c 0`, `BignumDtoa` lacked early\nreturn guards.\n\n3. **`Bignum` Shift and Exponent Operations**:\n- `Bignum::ShiftLeft(shift_amount)`: if `shift_amount \u003c\u003d 0`,\nnon-positive shifts are a no-op, but previously called\n`BigitsShiftLeft(local_shift)` which triggered undefined behavior on\nnegative shifts.\n- `Bignum::MultiplyByPowerOfTen(exponent)`: checked `if (exponent \u003d\u003d 0)\nreturn;`. For `exponent \u003c 0`, it bypassed the multiplier loops and\ncalled `ShiftLeft(exponent)` with a negative shift amount.\n- `Bignum::AssignPowerUInt16(base, power_exponent)`: checked `if\n(power_exponent \u003d\u003d 0) return;`. Negative exponents bypassed the loops\nand called `ShiftLeft(shifts * power_exponent)`.\n\n### Solution\n1. In `DoubleToStringConverter::DoubleToAscii`, guard `(mode \u003d\u003d\nPRECISION \u0026\u0026 requested_digits \u003c\u003d 0) || (mode \u003d\u003d FIXED \u0026\u0026\nrequested_digits \u003c 0)` by returning early with an empty string, `*length\n\u003d 0`, and `*point \u003d 0`.\n2. In `BignumDtoa`, return early with an empty string, `*length \u003d 0`,\nand `*decimal_point \u003d 0` for `(mode \u003d\u003d BIGNUM_DTOA_PRECISION \u0026\u0026\nrequested_digits \u003c\u003d 0) || (mode \u003d\u003d BIGNUM_DTOA_FIXED \u0026\u0026 requested_digits\n\u003c 0)`.\n3. In `Bignum::ShiftLeft`, return early if `shift_amount \u003c\u003d 0`.\n4. In `Bignum::MultiplyByPowerOfTen` and `Bignum::AssignPowerUInt16`,\nchange checks to `\u003c\u003d 0`.\n5. Add regression test cases across `test/cctest/test-dtoa.cc`,\n`test/cctest/test-bignum-dtoa.cc`, and `test/cctest/test-bignum.cc`.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "614a5186c8180c9ce177c7d05ea4e36db50fa211",
      "old_mode": 33188,
      "old_path": "double-conversion/bignum-dtoa.cc",
      "new_id": "82de248d7ace87f5de6cf924b16e0a8021435d63",
      "new_mode": 33188,
      "new_path": "double-conversion/bignum-dtoa.cc"
    },
    {
      "type": "modify",
      "old_id": "c1476cca77bc8dc4001f3c6872f85e8873ccda01",
      "old_mode": 33188,
      "old_path": "double-conversion/bignum.cc",
      "new_id": "e4c6fa5c4802dcd6ba203b69db9f6fa059ab2a54",
      "new_mode": 33188,
      "new_path": "double-conversion/bignum.cc"
    },
    {
      "type": "modify",
      "old_id": "d0635432ffc779f6d09a920db0c8acbbc35fe014",
      "old_mode": 33188,
      "old_path": "double-conversion/double-to-string.cc",
      "new_id": "b5630b1d47e1d9223a39ec79c23472f7bee2b0fc",
      "new_mode": 33188,
      "new_path": "double-conversion/double-to-string.cc"
    },
    {
      "type": "modify",
      "old_id": "07d5a61ac68705c42a3f78bf234989bc92abeaaa",
      "old_mode": 33188,
      "old_path": "test/cctest/test-bignum-dtoa.cc",
      "new_id": "441da1b9a58044a3240c738bd990c5b9b49fd945",
      "new_mode": 33188,
      "new_path": "test/cctest/test-bignum-dtoa.cc"
    },
    {
      "type": "modify",
      "old_id": "f27dbc76d31645fab0446b1cd8404244b0635b2e",
      "old_mode": 33188,
      "old_path": "test/cctest/test-bignum.cc",
      "new_id": "0f860c7de1ebe6364807c0415632a61a001e593a",
      "new_mode": 33188,
      "new_path": "test/cctest/test-bignum.cc"
    },
    {
      "type": "modify",
      "old_id": "94771ea6df531087adb87563ace8c9656753200e",
      "old_mode": 33188,
      "old_path": "test/cctest/test-dtoa.cc",
      "new_id": "6330085da05d76ad1dd4abd34ec6ccb5b35c7419",
      "new_mode": 33188,
      "new_path": "test/cctest/test-dtoa.cc"
    }
  ]
}
