aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2018-08-08 15:13:49 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2018-08-08 17:31:49 +0200
commit960c744d0dfc8cd51a8e1c7399d4b50fc829458b (patch)
treeeba4db309d23bcac5a661b61be0e33525905485a
parent8df17e769fc14be8892c248aa366ad2b872a838e (diff)
downloadalpine_aports-960c744d0dfc8cd51a8e1c7399d4b50fc829458b.tar.bz2
alpine_aports-960c744d0dfc8cd51a8e1c7399d4b50fc829458b.tar.xz
alpine_aports-960c744d0dfc8cd51a8e1c7399d4b50fc829458b.zip
main/p7zip: security fixes (CVE-2018-5996, CVE-2018-10115)
fixes #8534
-rw-r--r--main/p7zip/APKBUILD18
-rw-r--r--main/p7zip/CVE-2018-10115.patch311
-rw-r--r--main/p7zip/CVE-2018-5996.patch221
3 files changed, 545 insertions, 5 deletions
diff --git a/main/p7zip/APKBUILD b/main/p7zip/APKBUILD
index ae8b960c3b..f76a19cf6f 100644
--- a/main/p7zip/APKBUILD
+++ b/main/p7zip/APKBUILD
@@ -3,7 +3,7 @@
3# Maintainer: Natanael Copa <ncopa@alpinelinux.org> 3# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
4pkgname=p7zip 4pkgname=p7zip
5pkgver=16.02 5pkgver=16.02
6pkgrel=2 6pkgrel=3
7pkgdesc="A command-line port of the 7zip compression utility" 7pkgdesc="A command-line port of the 7zip compression utility"
8url="http://p7zip.sourceforge.net" 8url="http://p7zip.sourceforge.net"
9arch="all" 9arch="all"
@@ -13,14 +13,20 @@ depends=""
13makedepends="bash yasm nasm" 13makedepends="bash yasm nasm"
14source="http://downloads.sourceforge.net/sourceforge/$pkgname/${pkgname}_${pkgver}_src_all.tar.bz2 14source="http://downloads.sourceforge.net/sourceforge/$pkgname/${pkgname}_${pkgver}_src_all.tar.bz2
15 CVE-2016-9296.patch 15 CVE-2016-9296.patch
16 CVE-2017-17969.patch" 16 CVE-2017-17969.patch
17 CVE-2018-5996.patch
18 CVE-2018-10115.patch
19 "
17builddir="$srcdir/${pkgname}_$pkgver" 20builddir="$srcdir/${pkgname}_$pkgver"
18 21
19# secfixes: 22# secfixes:
20# 16.02-r1: 23# 16.02-r3:
21# - CVE-2016-9296 24# - CVE-2018-5996
25# - CVE-2018-10115
22# 16.02-r2: 26# 16.02-r2:
23# - CVE-2017-17969 27# - CVE-2017-17969
28# 16.02-r1:
29# - CVE-2016-9296
24 30
25prepare() { 31prepare() {
26 default_prepare || return 1 32 default_prepare || return 1
@@ -57,4 +63,6 @@ package() {
57 63
58sha512sums="d2c4d53817f96bb4c7683f42045198d4cd509cfc9c3e2cb85c8d9dc4ab6dfa7496449edeac4e300ecf986a9cbbc90bd8f8feef8156895d94617c04e507add55f p7zip_16.02_src_all.tar.bz2 64sha512sums="d2c4d53817f96bb4c7683f42045198d4cd509cfc9c3e2cb85c8d9dc4ab6dfa7496449edeac4e300ecf986a9cbbc90bd8f8feef8156895d94617c04e507add55f p7zip_16.02_src_all.tar.bz2
597a7fddf4122c3f5d4632640149a94c285a18515f38510388709c2fb9ecd450f9f34ae2e5fe4926c1c68507567b0affa2c8e9194c732673171dd5ee625192b194 CVE-2016-9296.patch 657a7fddf4122c3f5d4632640149a94c285a18515f38510388709c2fb9ecd450f9f34ae2e5fe4926c1c68507567b0affa2c8e9194c732673171dd5ee625192b194 CVE-2016-9296.patch
6022b6437770f2fb70675ed6971239ec3d40d5b9c7e1c5aa28c670d082bd2e7d861863f2f00feacec759eab216081dc49544b980b2ebe9fe40c7d0d1ca1dfc3069 CVE-2017-17969.patch" 6622b6437770f2fb70675ed6971239ec3d40d5b9c7e1c5aa28c670d082bd2e7d861863f2f00feacec759eab216081dc49544b980b2ebe9fe40c7d0d1ca1dfc3069 CVE-2017-17969.patch
677962a03430b94aec7c93d6dabee340f4f5915d728ba4df0dcaae483ab9c29115818e5e944572a3fd910addad8799c6a1e3911f6a0a02b661f804eea11c3a0f40 CVE-2018-5996.patch
68757d0f50ccce2a21dce81f165a9f408a71ea53c226ef29b4d3843f30b2fc518d06cd784e2de644904813cd16a87f24387c5cc35c2499b1df9d86377057be032a CVE-2018-10115.patch"
diff --git a/main/p7zip/CVE-2018-10115.patch b/main/p7zip/CVE-2018-10115.patch
new file mode 100644
index 0000000000..7d9c4bf81f
--- /dev/null
+++ b/main/p7zip/CVE-2018-10115.patch
@@ -0,0 +1,311 @@
1From: Robert Luberda <robert@debian.org>
2Date: Tue, 29 May 2018 23:59:09 +0200
3Subject: Fix CVE-2018-10115
4
5Apply "patch" taken from https://landave.io/files/patch_7zip_CVE-2018-10115.txt
6
7
8Bugs-Debian: https://bugs.debian.org/897674
9---
10 CPP/7zip/Compress/Rar1Decoder.cpp | 16 +++++++++++-----
11 CPP/7zip/Compress/Rar1Decoder.h | 3 ++-
12 CPP/7zip/Compress/Rar2Decoder.cpp | 17 +++++++++++++----
13 CPP/7zip/Compress/Rar2Decoder.h | 3 ++-
14 CPP/7zip/Compress/Rar3Decoder.cpp | 19 +++++++++++++++----
15 CPP/7zip/Compress/Rar3Decoder.h | 3 ++-
16 CPP/7zip/Compress/Rar5Decoder.cpp | 8 ++++++++
17 CPP/7zip/Compress/Rar5Decoder.h | 1 +
18 8 files changed, 54 insertions(+), 16 deletions(-)
19
20diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
21index 68030c7..8c890c8 100644
22--- a/CPP/7zip/Compress/Rar1Decoder.cpp
23+++ b/CPP/7zip/Compress/Rar1Decoder.cpp
24@@ -29,7 +29,7 @@ public:
25 };
26 */
27
28-CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
29+CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false), _errorMode(false) { }
30
31 void CDecoder::InitStructures()
32 {
33@@ -345,7 +345,7 @@ void CDecoder::GetFlagsBuf()
34
35 void CDecoder::InitData()
36 {
37- if (!m_IsSolid)
38+ if (!_isSolid)
39 {
40 AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
41 AvrPlc = 0x3500;
42@@ -391,6 +391,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
43 if (inSize == NULL || outSize == NULL)
44 return E_INVALIDARG;
45
46+ if (_isSolid && !_solidAllowed)
47+ return S_FALSE;
48+
49+ _solidAllowed = false;
50+
51 if (!m_OutWindowStream.Create(kHistorySize))
52 return E_OUTOFMEMORY;
53 if (!m_InBitStream.Create(1 << 20))
54@@ -398,13 +403,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
55
56 m_UnpackSize = (Int64)*outSize;
57 m_OutWindowStream.SetStream(outStream);
58- m_OutWindowStream.Init(m_IsSolid);
59+ m_OutWindowStream.Init(_isSolid);
60 m_InBitStream.SetStream(inStream);
61 m_InBitStream.Init();
62
63 // CCoderReleaser coderReleaser(this);
64 InitData();
65- if (!m_IsSolid)
66+ if (!_isSolid)
67 {
68 _errorMode = false;
69 InitStructures();
70@@ -475,6 +480,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
71 }
72 if (m_UnpackSize < 0)
73 return S_FALSE;
74+ _solidAllowed = true;
75 return m_OutWindowStream.Flush();
76 }
77
78@@ -491,7 +497,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
79 {
80 if (size < 1)
81 return E_INVALIDARG;
82- m_IsSolid = ((data[0] & 1) != 0);
83+ _isSolid = ((data[0] & 1) != 0);
84 return S_OK;
85 }
86
87diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
88index 01b606b..8abb3a3 100644
89--- a/CPP/7zip/Compress/Rar1Decoder.h
90+++ b/CPP/7zip/Compress/Rar1Decoder.h
91@@ -38,7 +38,8 @@ public:
92 UInt32 LastLength;
93
94 Int64 m_UnpackSize;
95- bool m_IsSolid;
96+ bool _isSolid;
97+ bool _solidAllowed;
98 bool _errorMode;
99
100 UInt32 ReadBits(int numBits);
101diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
102index 0580c8d..be8d842 100644
103--- a/CPP/7zip/Compress/Rar2Decoder.cpp
104+++ b/CPP/7zip/Compress/Rar2Decoder.cpp
105@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
106 static const UInt32 kWindowReservSize = (1 << 22) + 256;
107
108 CDecoder::CDecoder():
109- m_IsSolid(false),
110+ _isSolid(false),
111+ _solidAllowed(false),
112 m_TablesOK(false)
113 {
114 }
115@@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
116 if (inSize == NULL || outSize == NULL)
117 return E_INVALIDARG;
118
119+ if (_isSolid && !_solidAllowed)
120+ return S_FALSE;
121+ _solidAllowed = false;
122+
123 if (!m_OutWindowStream.Create(kHistorySize))
124 return E_OUTOFMEMORY;
125 if (!m_InBitStream.Create(1 << 20))
126@@ -330,12 +335,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
127 UInt64 pos = 0, unPackSize = *outSize;
128
129 m_OutWindowStream.SetStream(outStream);
130- m_OutWindowStream.Init(m_IsSolid);
131+ m_OutWindowStream.Init(_isSolid);
132 m_InBitStream.SetStream(inStream);
133 m_InBitStream.Init();
134
135 // CCoderReleaser coderReleaser(this);
136- if (!m_IsSolid)
137+ if (!_isSolid)
138 {
139 InitStructures();
140 if (unPackSize == 0)
141@@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
142 if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
143 if (!ReadTables())
144 return S_FALSE;
145+ _solidAllowed = true;
146 return S_OK;
147 }
148 if (!ReadTables())
149@@ -386,6 +392,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
150
151 if (!ReadLastTables())
152 return S_FALSE;
153+
154+ _solidAllowed = true;
155+
156 return m_OutWindowStream.Flush();
157 }
158
159@@ -402,7 +411,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
160 {
161 if (size < 1)
162 return E_INVALIDARG;
163- m_IsSolid = ((data[0] & 1) != 0);
164+ _isSolid = ((data[0] & 1) != 0);
165 return S_OK;
166 }
167
168diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
169index 0e9005f..370bce2 100644
170--- a/CPP/7zip/Compress/Rar2Decoder.h
171+++ b/CPP/7zip/Compress/Rar2Decoder.h
172@@ -138,7 +138,8 @@ class CDecoder :
173 Byte m_LastLevels[kMaxTableSize];
174
175 UInt64 m_PackSize;
176- bool m_IsSolid;
177+ bool _isSolid;
178+ bool _solidAllowed;
179 bool m_TablesOK;
180
181 void InitStructures();
182diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
183index 6cb8a6a..7b85833 100644
184--- a/CPP/7zip/Compress/Rar3Decoder.cpp
185+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
186@@ -92,7 +92,8 @@ CDecoder::CDecoder():
187 _writtenFileSize(0),
188 _vmData(0),
189 _vmCode(0),
190- m_IsSolid(false),
191+ _isSolid(false),
192+ _solidAllowed(false),
193 _errorMode(false)
194 {
195 Ppmd7_Construct(&_ppmd);
196@@ -821,7 +822,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
197 {
198 _writtenFileSize = 0;
199 _unsupportedFilter = false;
200- if (!m_IsSolid)
201+ if (!_isSolid)
202 {
203 _lzSize = 0;
204 _winPos = 0;
205@@ -840,12 +841,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
206 if (_errorMode)
207 return S_FALSE;
208
209- if (!m_IsSolid || !TablesRead)
210+ if (!_isSolid || !TablesRead)
211 {
212 bool keepDecompressing;
213 RINOK(ReadTables(keepDecompressing));
214 if (!keepDecompressing)
215+ {
216+ _solidAllowed = true;
217 return S_OK;
218+ }
219 }
220
221 for (;;)
222@@ -870,6 +874,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
223 if (!keepDecompressing)
224 break;
225 }
226+
227+ _solidAllowed = true;
228+
229 RINOK(WriteBuf());
230 UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
231 RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
232@@ -890,6 +897,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
233 if (!inSize)
234 return E_INVALIDARG;
235
236+ if (_isSolid && !_solidAllowed)
237+ return S_FALSE;
238+ _solidAllowed = false;
239+
240 if (!_vmData)
241 {
242 _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
243@@ -928,7 +939,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
244 {
245 if (size < 1)
246 return E_INVALIDARG;
247- m_IsSolid = ((data[0] & 1) != 0);
248+ _isSolid = ((data[0] & 1) != 0);
249 return S_OK;
250 }
251
252diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
253index 2f72d7d..32c8943 100644
254--- a/CPP/7zip/Compress/Rar3Decoder.h
255+++ b/CPP/7zip/Compress/Rar3Decoder.h
256@@ -191,7 +191,8 @@ class CDecoder:
257 CRecordVector<CTempFilter *> _tempFilters;
258 UInt32 _lastFilter;
259
260- bool m_IsSolid;
261+ bool _isSolid;
262+ bool _solidAllowed;
263 bool _errorMode;
264
265 bool _lzMode;
266diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp
267index dc8830f..a826d5a 100644
268--- a/CPP/7zip/Compress/Rar5Decoder.cpp
269+++ b/CPP/7zip/Compress/Rar5Decoder.cpp
270@@ -72,6 +72,7 @@ CDecoder::CDecoder():
271 _writtenFileSize(0),
272 _dictSizeLog(0),
273 _isSolid(false),
274+ _solidAllowed(false),
275 _wasInit(false),
276 _inputBuf(NULL)
277 {
278@@ -801,7 +802,10 @@ HRESULT CDecoder::CodeReal()
279 */
280
281 if (res == S_OK)
282+ {
283+ _solidAllowed = true;
284 res = res2;
285+ }
286
287 if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize)
288 return S_FALSE;
289@@ -821,6 +825,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
290 {
291 try
292 {
293+ if (_isSolid && !_solidAllowed)
294+ return S_FALSE;
295+ _solidAllowed = false;
296+
297 if (_dictSizeLog >= sizeof(size_t) * 8)
298 return E_NOTIMPL;
299
300diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h
301index b0a4dd1..3db5018 100644
302--- a/CPP/7zip/Compress/Rar5Decoder.h
303+++ b/CPP/7zip/Compress/Rar5Decoder.h
304@@ -271,6 +271,7 @@ class CDecoder:
305 Byte _dictSizeLog;
306 bool _tableWasFilled;
307 bool _isSolid;
308+ bool _solidAllowed;
309 bool _wasInit;
310
311 UInt32 _reps[kNumReps];
diff --git a/main/p7zip/CVE-2018-5996.patch b/main/p7zip/CVE-2018-5996.patch
new file mode 100644
index 0000000000..6733bff918
--- /dev/null
+++ b/main/p7zip/CVE-2018-5996.patch
@@ -0,0 +1,221 @@
1From: Robert Luberda <robert@debian.org>
2Date: Sun, 28 Jan 2018 23:47:40 +0100
3Subject: CVE-2018-5996
4
5Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by
6applying a few changes from 7Zip 18.00-beta.
7
8Bug-Debian: https://bugs.debian.org/#888314
9---
10 CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++----
11 CPP/7zip/Compress/Rar1Decoder.h | 1 +
12 CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++-
13 CPP/7zip/Compress/Rar2Decoder.h | 1 +
14 CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++---
15 CPP/7zip/Compress/Rar3Decoder.h | 2 ++
16 6 files changed, 42 insertions(+), 8 deletions(-)
17
18diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
19index 1aaedcc..68030c7 100644
20--- a/CPP/7zip/Compress/Rar1Decoder.cpp
21+++ b/CPP/7zip/Compress/Rar1Decoder.cpp
22@@ -29,7 +29,7 @@ public:
23 };
24 */
25
26-CDecoder::CDecoder(): m_IsSolid(false) { }
27+CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
28
29 void CDecoder::InitStructures()
30 {
31@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
32 InitData();
33 if (!m_IsSolid)
34 {
35+ _errorMode = false;
36 InitStructures();
37 InitHuff();
38 }
39+
40+ if (_errorMode)
41+ return S_FALSE;
42+
43 if (m_UnpackSize > 0)
44 {
45 GetFlagsBuf();
46@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
47 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
48 {
49 try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
50- catch(const CInBufferException &e) { return e.ErrorCode; }
51- catch(const CLzOutWindowException &e) { return e.ErrorCode; }
52- catch(...) { return S_FALSE; }
53+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
54+ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; }
55+ catch(...) { _errorMode = true; return S_FALSE; }
56 }
57
58 STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
59diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
60index 630f089..01b606b 100644
61--- a/CPP/7zip/Compress/Rar1Decoder.h
62+++ b/CPP/7zip/Compress/Rar1Decoder.h
63@@ -39,6 +39,7 @@ public:
64
65 Int64 m_UnpackSize;
66 bool m_IsSolid;
67+ bool _errorMode;
68
69 UInt32 ReadBits(int numBits);
70 HRESULT CopyBlock(UInt32 distance, UInt32 len);
71diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
72index b3f2b4b..0580c8d 100644
73--- a/CPP/7zip/Compress/Rar2Decoder.cpp
74+++ b/CPP/7zip/Compress/Rar2Decoder.cpp
75@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
76 static const UInt32 kWindowReservSize = (1 << 22) + 256;
77
78 CDecoder::CDecoder():
79- m_IsSolid(false)
80+ m_IsSolid(false),
81+ m_TablesOK(false)
82 {
83 }
84
85@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB
86
87 bool CDecoder::ReadTables(void)
88 {
89+ m_TablesOK = false;
90+
91 Byte levelLevels[kLevelTableSize];
92 Byte newLevels[kMaxTableSize];
93 m_AudioMode = (ReadBits(1) == 1);
94@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void)
95 }
96
97 memcpy(m_LastLevels, newLevels, kMaxTableSize);
98+ m_TablesOK = true;
99+
100 return true;
101 }
102
103@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
104 return S_FALSE;
105 }
106
107+ if (!m_TablesOK)
108+ return S_FALSE;
109+
110 UInt64 startPos = m_OutWindowStream.GetProcessedSize();
111 while (pos < unPackSize)
112 {
113diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
114index 3a0535c..0e9005f 100644
115--- a/CPP/7zip/Compress/Rar2Decoder.h
116+++ b/CPP/7zip/Compress/Rar2Decoder.h
117@@ -139,6 +139,7 @@ class CDecoder :
118
119 UInt64 m_PackSize;
120 bool m_IsSolid;
121+ bool m_TablesOK;
122
123 void InitStructures();
124 UInt32 ReadBits(unsigned numBits);
125diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
126index 3bf2513..6cb8a6a 100644
127--- a/CPP/7zip/Compress/Rar3Decoder.cpp
128+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
129@@ -92,7 +92,8 @@ CDecoder::CDecoder():
130 _writtenFileSize(0),
131 _vmData(0),
132 _vmCode(0),
133- m_IsSolid(false)
134+ m_IsSolid(false),
135+ _errorMode(false)
136 {
137 Ppmd7_Construct(&_ppmd);
138 }
139@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
140 return InitPPM();
141 }
142
143+ TablesRead = false;
144+ TablesOK = false;
145+
146 _lzMode = true;
147 PrevAlignBits = 0;
148 PrevAlignCount = 0;
149@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
150 }
151 }
152 }
153+ if (InputEofError())
154+ return S_FALSE;
155+
156 TablesRead = true;
157
158 // original code has check here:
159@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
160 RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
161
162 memcpy(m_LastLevels, newLevels, kTablesSizesSum);
163+
164+ TablesOK = true;
165+
166 return S_OK;
167 }
168
169@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
170 PpmEscChar = 2;
171 PpmError = true;
172 InitFilters();
173+ _errorMode = false;
174 }
175+
176+ if (_errorMode)
177+ return S_FALSE;
178+
179 if (!m_IsSolid || !TablesRead)
180 {
181 bool keepDecompressing;
182@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
183 bool keepDecompressing;
184 if (_lzMode)
185 {
186+ if (!TablesOK)
187+ return S_FALSE;
188 RINOK(DecodeLZ(keepDecompressing))
189 }
190 else
191@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
192 _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
193 return CodeReal(progress);
194 }
195- catch(const CInBufferException &e) { return e.ErrorCode; }
196- catch(...) { return S_FALSE; }
197+ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
198+ catch(...) { _errorMode = true; return S_FALSE; }
199 // CNewException is possible here. But probably CNewException is caused
200 // by error in data stream.
201 }
202diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
203index c130cec..2f72d7d 100644
204--- a/CPP/7zip/Compress/Rar3Decoder.h
205+++ b/CPP/7zip/Compress/Rar3Decoder.h
206@@ -192,6 +192,7 @@ class CDecoder:
207 UInt32 _lastFilter;
208
209 bool m_IsSolid;
210+ bool _errorMode;
211
212 bool _lzMode;
213 bool _unsupportedFilter;
214@@ -200,6 +201,7 @@ class CDecoder:
215 UInt32 PrevAlignCount;
216
217 bool TablesRead;
218+ bool TablesOK;
219
220 CPpmd7 _ppmd;
221 int PpmEscChar;