)]}'
{
  "commit": "b54eac58daf563e9150cc6abce7631ac71b999aa",
  "tree": "c4720dd60776b99180dba9dc044f8eb35565cab3",
  "parents": [
    "b357f083ea5ae0ee7b09a65a48621f345e710588"
  ],
  "author": {
    "name": "jeffhuang",
    "email": "jeff@docker.xydrsucermoubd24xgo33yhsgd.bx.internal.cloudapp.net",
    "time": "Sun Apr 19 04:24:41 2026 +0000"
  },
  "committer": {
    "name": "Vignesh Venkatasubramanian",
    "email": "vigneshvg@users.noreply.github.com",
    "time": "Mon Apr 20 15:33:28 2026 -0700"
  },
  "message": "Android JNI: reject invalid length at direct buffer entry points\n\nThe public Android JNI decoder entry points accept a signed int length\nand forward it, unchecked, into size_t boundaries. A negative length\n(e.g. -1) sign-extends to a near-SIZE_MAX value, so the parser trusts\nthe inflated advertised size and reads past the real direct-buffer\nallocation. See issue #3177 for the ASan heap-buffer-overflow\nreproducer.\n\nAdd a ValidateDirectBuffer() helper that rejects negative lengths,\nnon-direct buffers, lengths larger than the direct buffer capacity,\nand null addresses before any cast to size_t. Apply it at every\npublic JNI entry point consuming (ByteBuffer, int) — isAvifImage,\ngetInfo, decode, and createDecoder. Change the internal\nCreateDecoderAndParse() helper to take size_t length so the\nsigned-to-unsigned sign-extension is gone from the internal path too.\n\nAdd an Android instrumentation regression test\n(AvifDecoderLengthValidationTest) that covers length \u003d -1,\nlength \u003d Integer.MIN_VALUE, length \u003d capacity + 1,\nlength \u003d Integer.MAX_VALUE, heap-backed buffers, and the happy path\non a valid image, verifying every case returns the clean-failure\ncontract (false / null) instead of crashing.\n\nLeaves src/read.c, src/stream.c, and the Java public API surface\n(AvifDecoder.java) unchanged: the fix enforces the contract at the\nJNI boundary where the signed length enters.\n\nFixes #3177\n\nCo-Authored-By: Claude Opus 4.7 (1M context) \u003cnoreply@anthropic.com\u003e\n",
  "tree_diff": [
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "38f623b1d37a30e4e1c7dc278320301ab9eb451d",
      "new_mode": 33188,
      "new_path": "android_jni/avifandroidjni/src/androidTest/java/org/aomedia/avif/android/AvifDecoderLengthValidationTest.java"
    },
    {
      "type": "modify",
      "old_id": "83eb3e3d936562bc457f2ab0d662a6f855683e23",
      "old_mode": 33188,
      "old_path": "android_jni/avifandroidjni/src/main/jni/libavif_jni.cc",
      "new_id": "cec1c880e5bda4fb93a222e109a9454f1dd59fef",
      "new_mode": 33188,
      "new_path": "android_jni/avifandroidjni/src/main/jni/libavif_jni.cc"
    }
  ]
}
