From d8beef1f0bc0330756e5ea31dbc1a42232e1769e Mon Sep 17 00:00:00 2001 From: cjee21 <77721854+cjee21@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:24:10 +0800 Subject: [PATCH 1/4] Bitstream: Prevent array overreads and undefined behaviour --- Source/ZenLib/BitStream_Fast.h | 18 ++++++++++++++++++ Source/ZenLib/BitStream_LE.h | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Source/ZenLib/BitStream_Fast.h b/Source/ZenLib/BitStream_Fast.h index 9706333..455259e 100644 --- a/Source/ZenLib/BitStream_Fast.h +++ b/Source/ZenLib/BitStream_Fast.h @@ -80,6 +80,9 @@ class BitStream_Fast 0x1f, 0x3f, 0x7f, 0xff, }; + if (HowMany==0 || HowMany>8) + return 0; + if (HowMany<=(Buffer_Size%8)) { Buffer_Size-=HowMany; @@ -117,6 +120,9 @@ class BitStream_Fast 0x1fff, 0x3fff, 0x7fff, 0xffff, }; + if (HowMany==0 || HowMany>16) + return 0; + if (HowMany<=(Buffer_Size%8)) { Buffer_Size-=HowMany; @@ -164,6 +170,9 @@ class BitStream_Fast 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, }; + if (HowMany==0 || HowMany>32) + return 0; + if (HowMany<=(Buffer_Size%8)) { Buffer_Size-=HowMany; @@ -263,6 +272,9 @@ class BitStream_Fast 0x1f, 0x3f, 0x7f, 0xff, }; + if (HowMany==0 || HowMany>8) + return 0; + if (HowMany<=(Buffer_Size%8)) return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany]; @@ -295,6 +307,9 @@ class BitStream_Fast 0x1fff, 0x3fff, 0x7fff, 0xffff, }; + if (HowMany==0 || HowMany>16) + return 0; + if (HowMany<=(Buffer_Size%8)) return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany]; @@ -341,6 +356,9 @@ class BitStream_Fast 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, }; + if (HowMany==0 || HowMany>32) + return 0; + if (HowMany<=(Buffer_Size%8)) return (LastByte>>((Buffer_Size-HowMany)%8))&Mask[HowMany]; diff --git a/Source/ZenLib/BitStream_LE.h b/Source/ZenLib/BitStream_LE.h index 20147c0..59dc995 100644 --- a/Source/ZenLib/BitStream_LE.h +++ b/Source/ZenLib/BitStream_LE.h @@ -65,6 +65,10 @@ class BitStream_LE : public BitStream 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, }; + + if (HowMany==0 || HowMany>32) + return 0; + unsigned long m=Mask[HowMany]; HowMany+=endbit; @@ -103,6 +107,18 @@ class BitStream_LE : public BitStream void Skip(size_t bits) { + if (bits==0) + return; + if (bits>32) //Get is only for <=32 bits + { + do { + Get(32); + bits-=32; + } while (bits>32); + if (bits) + Get(bits); + return; + } Get(bits); } From 6ed5e3e4a7edefd86430e79c7bf14ec69456f289 Mon Sep 17 00:00:00 2001 From: cjee21 <77721854+cjee21@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:51:10 +0800 Subject: [PATCH 2/4] BitstreamLE: Fix Byte_Align --- Source/ZenLib/BitStream_LE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ZenLib/BitStream_LE.h b/Source/ZenLib/BitStream_LE.h index 59dc995..7385bbe 100644 --- a/Source/ZenLib/BitStream_LE.h +++ b/Source/ZenLib/BitStream_LE.h @@ -130,7 +130,7 @@ class BitStream_LE : public BitStream void Byte_Align() { if (endbit) - Get(endbit); + Get(8-endbit); }; size_t Offset_Get() From 41179524cc7d4c7e55a6dd52f1f94f1276b81ae4 Mon Sep 17 00:00:00 2001 From: cjee21 <77721854+cjee21@users.noreply.github.com> Date: Wed, 4 Nov 2026 20:25:23 +0800 Subject: [PATCH 3/4] Bitstream: Stop bit skips on buffer underrun Return immediately when a 32-bit skip or read fails in either bitstream implementation, preventing further processing after the buffer is exhausted. --- Source/ZenLib/BitStream.h | 2 ++ Source/ZenLib/BitStream_LE.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Source/ZenLib/BitStream.h b/Source/ZenLib/BitStream.h index e23b848..85e24a7 100644 --- a/Source/ZenLib/BitStream.h +++ b/Source/ZenLib/BitStream.h @@ -183,6 +183,8 @@ class BitStream do { Skip(32); + if (BufferUnderRun) + return; HowMany-=32; } while(HowMany>32); diff --git a/Source/ZenLib/BitStream_LE.h b/Source/ZenLib/BitStream_LE.h index 7385bbe..55f85ea 100644 --- a/Source/ZenLib/BitStream_LE.h +++ b/Source/ZenLib/BitStream_LE.h @@ -113,6 +113,8 @@ class BitStream_LE : public BitStream { do { Get(32); + if (!buffer) + return; bits-=32; } while (bits>32); if (bits) From 2e986ed53f9e9a8dd0a5e622441ec86eabe83ff8 Mon Sep 17 00:00:00 2001 From: Jerome Martinez Date: Sat, 7 Nov 2026 17:28:49 +0100 Subject: [PATCH 4/4] BitstreamLE: Preserve previous offset on invalid reads --- Source/ZenLib/BitStream_LE.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/ZenLib/BitStream_LE.h b/Source/ZenLib/BitStream_LE.h index 55f85ea..ac209f3 100644 --- a/Source/ZenLib/BitStream_LE.h +++ b/Source/ZenLib/BitStream_LE.h @@ -51,8 +51,6 @@ class BitStream_LE : public BitStream int32u Get (size_t HowMany) { - ptr_BeforeLastCall=ptr; - long ret; static const int32u Mask[33]={ 0x00000000, @@ -69,6 +67,8 @@ class BitStream_LE : public BitStream if (HowMany==0 || HowMany>32) return 0; + ptr_BeforeLastCall=ptr; + unsigned long m=Mask[HowMany]; HowMany+=endbit;