Commit d7ec45ab for openh264

commit d7ec45ab1fe4590473968004e38fe76257b7c4c4
Author: BenzhengZhang <140143892+BenzhengZhang@users.noreply.github.com>
Date:   Fri Aug 28 15:50:55 2026 +0800

    decoder: validate GMP BufferLength32 lengths before rewrite (#3971)

    * decoder: validate GMP BufferLength32 lengths before rewrite

    * decoder: harden GMP_BufferLength32 rewrite bounds

    ---------

    Co-authored-by: benzzhan <benzzhan@cisco.com>

diff --git a/module/gmp-openh264.cpp b/module/gmp-openh264.cpp
index 4380c9c9..6354f315 100644
--- a/module/gmp-openh264.cpp
+++ b/module/gmp-openh264.cpp
@@ -930,14 +930,25 @@ class OpenH264VideoDecoder : public GMPVideoDecoder, public RefCounted {
       break;

     case GMP_BufferLength32: {
+      static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
       uint8_t* start_code = inputFrame->Buffer();
-      // start code should be at least four bytes from the end or we risk
-      // reading/writing outside the buffer.
-      while (start_code < inputFrame->Buffer() + inputFrame->Size() - 4) {
-        static const uint8_t code[] = { 0x00, 0x00, 0x00, 0x01 };
-        uint8_t* lenp = start_code;
-        start_code += * (reinterpret_cast<int32_t*> (lenp));
-        memcpy (lenp, code, 4);
+      uint32_t remaining = inputFrame->Size();
+
+      // Keep old semantics: length field includes the 4-byte length header.
+      while (remaining >= sizeof (uint32_t)) {
+        uint32_t nal_length = 0;
+        memcpy (&nal_length, start_code, sizeof (nal_length));
+        if (nal_length <= sizeof (uint32_t) || nal_length > remaining) {
+          GMPLOG (GL_ERROR, "Malformed GMP_BufferLength32 frame: nal_length="
+                  << nal_length << " remaining=" << remaining);
+          inputFrame->Destroy();
+          Error (GMPDecodeErr);
+          return;
+        }
+
+        memcpy (start_code, code, sizeof (code));
+        start_code += nal_length;
+        remaining -= nal_length;
       }
     }
     break;