summaryrefslogtreecommitdiff
blob: 95644d6921e75fd30767615b55132a3a0d3c36ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
See https://trac.kodi.tv/ticket/17510
diff --git a/lib/UnrarXLib/rarvm.cpp b/lib/UnrarXLib/rarvm.cpp
index 901c35dcb4..42df0a0110 100644
--- a/lib/UnrarXLib/rarvm.cpp
+++ b/lib/UnrarXLib/rarvm.cpp
@@ -873,14 +873,16 @@ void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
       break;
     case VMSF_DELTA:
       {
-        int DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2;
-        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
-        if (DataSize>=VM_GLOBALMEMADDR/2)
-          break;
-        for (int CurChannel=0;CurChannel<Channels;CurChannel++)
+        uint DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2;
+        if (DataSize>VM_MEMSIZE/2 || Channels>MAX3_UNPACK_CHANNELS || Channels==0)
+          break;
+
+        // Bytes from same channels are grouped to continual data blocks,
+        // so we need to place them back to their interleaving positions.
+        for (uint CurChannel=0;CurChannel<Channels;CurChannel++)
         {
           byte PrevByte=0;
-          for (int DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels)
+          for (uint DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels)
             Mem[DestPos]=(PrevByte-=Mem[SrcPos++]);
         }
       }
diff --git a/lib/UnrarXLib/unpack.hpp b/lib/UnrarXLib/unpack.hpp
index 83fb0f0254..36ac30d181 100644
--- a/lib/UnrarXLib/unpack.hpp
+++ b/lib/UnrarXLib/unpack.hpp
@@ -1,6 +1,12 @@
 #ifndef _RAR_UNPACK_
 #define _RAR_UNPACK_
 
+// Limit maximum number of channels in RAR3 delta filter to some reasonable
+// value to prevent too slow processing of corrupt archives with invalid
+// channels number. Must be equal or larger than v3_MAX_FILTER_CHANNELS.
+// No need to provide it for RAR5, which uses only 5 bits to store channels.
+#define MAX3_UNPACK_CHANNELS      1024
+
 enum BLOCK_TYPES {BLOCK_LZ,BLOCK_PPM};
 
 struct Decode