aboutsummaryrefslogtreecommitdiffstats
path: root/main/p7zip
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 15:13:49 +0000
commit916b50fbdafda4e285e59c6b59805040daee9fce (patch)
tree537be9bffbeef66f3361693ecd5811d0d3ecb194 /main/p7zip
parent5221b8372ca3e245b6f665cdb710ce414c6fbc1a (diff)
downloadaports-916b50fbdafda4e285e59c6b59805040daee9fce.tar.bz2
aports-916b50fbdafda4e285e59c6b59805040daee9fce.tar.xz
main/p7zip: security fixes (CVE-2018-5996, CVE-2018-10115)
ref #8531
Diffstat (limited to 'main/p7zip')
-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 722f7a4bf9..2d0cc63cfb 100644
--- a/main/p7zip/APKBUILD
+++ b/main/p7zip/APKBUILD
@@ -3,7 +3,7 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=p7zip
pkgver=16.02
-pkgrel=2
+pkgrel=3
pkgdesc="A command-line port of the 7zip compression utility"
url="http://p7zip.sourceforge.net"
arch="all"
@@ -13,14 +13,20 @@ depends=""
makedepends="bash yasm nasm"
source="http://downloads.sourceforge.net/sourceforge/$pkgname/${pkgname}_${pkgver}_src_all.tar.bz2
CVE-2016-9296.patch
- CVE-2017-17969.patch"
+ CVE-2017-17969.patch
+ CVE-2018-5996.patch
+ CVE-2018-10115.patch
+ "
builddir="$srcdir/${pkgname}_$pkgver"
# secfixes:
-# 16.02-r1:
-# - CVE-2016-9296
+# 16.02-r3:
+# - CVE-2018-5996
+# - CVE-2018-10115
# 16.02-r2:
# - CVE-2017-17969
+# 16.02-r1:
+# - CVE-2016-9296
prepare() {
default_prepare
@@ -62,4 +68,6 @@ package() {
sha512sums="d2c4d53817f96bb4c7683f42045198d4cd509cfc9c3e2cb85c8d9dc4ab6dfa7496449edeac4e300ecf986a9cbbc90bd8f8feef8156895d94617c04e507add55f p7zip_16.02_src_all.tar.bz2
7a7fddf4122c3f5d4632640149a94c285a18515f38510388709c2fb9ecd450f9f34ae2e5fe4926c1c68507567b0affa2c8e9194c732673171dd5ee625192b194 CVE-2016-9296.patch
-22b6437770f2fb70675ed6971239ec3d40d5b9c7e1c5aa28c670d082bd2e7d861863f2f00feacec759eab216081dc49544b980b2ebe9fe40c7d0d1ca1dfc3069 CVE-2017-17969.patch"
+22b6437770f2fb70675ed6971239ec3d40d5b9c7e1c5aa28c670d082bd2e7d861863f2f00feacec759eab216081dc49544b980b2ebe9fe40c7d0d1ca1dfc3069 CVE-2017-17969.patch
+7962a03430b94aec7c93d6dabee340f4f5915d728ba4df0dcaae483ab9c29115818e5e944572a3fd910addad8799c6a1e3911f6a0a02b661f804eea11c3a0f40 CVE-2018-5996.patch
+757d0f50ccce2a21dce81f165a9f408a71ea53c226ef29b4d3843f30b2fc518d06cd784e2de644904813cd16a87f24387c5cc35c2499b1df9d86377057be032a 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 @@
+From: Robert Luberda <robert@debian.org>
+Date: Tue, 29 May 2018 23:59:09 +0200
+Subject: Fix CVE-2018-10115
+
+Apply "patch" taken from https://landave.io/files/patch_7zip_CVE-2018-10115.txt
+
+
+Bugs-Debian: https://bugs.debian.org/897674
+---
+ CPP/7zip/Compress/Rar1Decoder.cpp | 16 +++++++++++-----
+ CPP/7zip/Compress/Rar1Decoder.h | 3 ++-
+ CPP/7zip/Compress/Rar2Decoder.cpp | 17 +++++++++++++----
+ CPP/7zip/Compress/Rar2Decoder.h | 3 ++-
+ CPP/7zip/Compress/Rar3Decoder.cpp | 19 +++++++++++++++----
+ CPP/7zip/Compress/Rar3Decoder.h | 3 ++-
+ CPP/7zip/Compress/Rar5Decoder.cpp | 8 ++++++++
+ CPP/7zip/Compress/Rar5Decoder.h | 1 +
+ 8 files changed, 54 insertions(+), 16 deletions(-)
+
+diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
+index 68030c7..8c890c8 100644
+--- a/CPP/7zip/Compress/Rar1Decoder.cpp
++++ b/CPP/7zip/Compress/Rar1Decoder.cpp
+@@ -29,7 +29,7 @@ public:
+ };
+ */
+
+-CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
++CDecoder::CDecoder(): _isSolid(false), _solidAllowed(false), _errorMode(false) { }
+
+ void CDecoder::InitStructures()
+ {
+@@ -345,7 +345,7 @@ void CDecoder::GetFlagsBuf()
+
+ void CDecoder::InitData()
+ {
+- if (!m_IsSolid)
++ if (!_isSolid)
+ {
+ AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
+ AvrPlc = 0x3500;
+@@ -391,6 +391,11 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ if (inSize == NULL || outSize == NULL)
+ return E_INVALIDARG;
+
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++
++ _solidAllowed = false;
++
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 20))
+@@ -398,13 +403,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+
+ m_UnpackSize = (Int64)*outSize;
+ m_OutWindowStream.SetStream(outStream);
+- m_OutWindowStream.Init(m_IsSolid);
++ m_OutWindowStream.Init(_isSolid);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+
+ // CCoderReleaser coderReleaser(this);
+ InitData();
+- if (!m_IsSolid)
++ if (!_isSolid)
+ {
+ _errorMode = false;
+ InitStructures();
+@@ -475,6 +480,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ }
+ if (m_UnpackSize < 0)
+ return S_FALSE;
++ _solidAllowed = true;
+ return m_OutWindowStream.Flush();
+ }
+
+@@ -491,7 +497,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
+diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
+index 01b606b..8abb3a3 100644
+--- a/CPP/7zip/Compress/Rar1Decoder.h
++++ b/CPP/7zip/Compress/Rar1Decoder.h
+@@ -38,7 +38,8 @@ public:
+ UInt32 LastLength;
+
+ Int64 m_UnpackSize;
+- bool m_IsSolid;
++ bool _isSolid;
++ bool _solidAllowed;
+ bool _errorMode;
+
+ UInt32 ReadBits(int numBits);
+diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
+index 0580c8d..be8d842 100644
+--- a/CPP/7zip/Compress/Rar2Decoder.cpp
++++ b/CPP/7zip/Compress/Rar2Decoder.cpp
+@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
+ static const UInt32 kWindowReservSize = (1 << 22) + 256;
+
+ CDecoder::CDecoder():
+- m_IsSolid(false),
++ _isSolid(false),
++ _solidAllowed(false),
+ m_TablesOK(false)
+ {
+ }
+@@ -320,6 +321,10 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ if (inSize == NULL || outSize == NULL)
+ return E_INVALIDARG;
+
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
++
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+ if (!m_InBitStream.Create(1 << 20))
+@@ -330,12 +335,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ UInt64 pos = 0, unPackSize = *outSize;
+
+ m_OutWindowStream.SetStream(outStream);
+- m_OutWindowStream.Init(m_IsSolid);
++ m_OutWindowStream.Init(_isSolid);
+ m_InBitStream.SetStream(inStream);
+ m_InBitStream.Init();
+
+ // CCoderReleaser coderReleaser(this);
+- if (!m_IsSolid)
++ if (!_isSolid)
+ {
+ InitStructures();
+ if (unPackSize == 0)
+@@ -343,6 +348,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it: probably incorrect;
+ if (!ReadTables())
+ return S_FALSE;
++ _solidAllowed = true;
+ return S_OK;
+ }
+ if (!ReadTables())
+@@ -386,6 +392,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+
+ if (!ReadLastTables())
+ return S_FALSE;
++
++ _solidAllowed = true;
++
+ return m_OutWindowStream.Flush();
+ }
+
+@@ -402,7 +411,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
+diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
+index 0e9005f..370bce2 100644
+--- a/CPP/7zip/Compress/Rar2Decoder.h
++++ b/CPP/7zip/Compress/Rar2Decoder.h
+@@ -138,7 +138,8 @@ class CDecoder :
+ Byte m_LastLevels[kMaxTableSize];
+
+ UInt64 m_PackSize;
+- bool m_IsSolid;
++ bool _isSolid;
++ bool _solidAllowed;
+ bool m_TablesOK;
+
+ void InitStructures();
+diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
+index 6cb8a6a..7b85833 100644
+--- a/CPP/7zip/Compress/Rar3Decoder.cpp
++++ b/CPP/7zip/Compress/Rar3Decoder.cpp
+@@ -92,7 +92,8 @@ CDecoder::CDecoder():
+ _writtenFileSize(0),
+ _vmData(0),
+ _vmCode(0),
+- m_IsSolid(false),
++ _isSolid(false),
++ _solidAllowed(false),
+ _errorMode(false)
+ {
+ Ppmd7_Construct(&_ppmd);
+@@ -821,7 +822,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+ {
+ _writtenFileSize = 0;
+ _unsupportedFilter = false;
+- if (!m_IsSolid)
++ if (!_isSolid)
+ {
+ _lzSize = 0;
+ _winPos = 0;
+@@ -840,12 +841,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+ if (_errorMode)
+ return S_FALSE;
+
+- if (!m_IsSolid || !TablesRead)
++ if (!_isSolid || !TablesRead)
+ {
+ bool keepDecompressing;
+ RINOK(ReadTables(keepDecompressing));
+ if (!keepDecompressing)
++ {
++ _solidAllowed = true;
+ return S_OK;
++ }
+ }
+
+ for (;;)
+@@ -870,6 +874,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+ if (!keepDecompressing)
+ break;
+ }
++
++ _solidAllowed = true;
++
+ RINOK(WriteBuf());
+ UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
+@@ -890,6 +897,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
+ if (!inSize)
+ return E_INVALIDARG;
+
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
++
+ if (!_vmData)
+ {
+ _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
+@@ -928,7 +939,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
+diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
+index 2f72d7d..32c8943 100644
+--- a/CPP/7zip/Compress/Rar3Decoder.h
++++ b/CPP/7zip/Compress/Rar3Decoder.h
+@@ -191,7 +191,8 @@ class CDecoder:
+ CRecordVector<CTempFilter *> _tempFilters;
+ UInt32 _lastFilter;
+
+- bool m_IsSolid;
++ bool _isSolid;
++ bool _solidAllowed;
+ bool _errorMode;
+
+ bool _lzMode;
+diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp
+index dc8830f..a826d5a 100644
+--- a/CPP/7zip/Compress/Rar5Decoder.cpp
++++ b/CPP/7zip/Compress/Rar5Decoder.cpp
+@@ -72,6 +72,7 @@ CDecoder::CDecoder():
+ _writtenFileSize(0),
+ _dictSizeLog(0),
+ _isSolid(false),
++ _solidAllowed(false),
+ _wasInit(false),
+ _inputBuf(NULL)
+ {
+@@ -801,7 +802,10 @@ HRESULT CDecoder::CodeReal()
+ */
+
+ if (res == S_OK)
++ {
++ _solidAllowed = true;
+ res = res2;
++ }
+
+ if (res == S_OK && _unpackSize_Defined && _writtenFileSize != _unpackSize)
+ return S_FALSE;
+@@ -821,6 +825,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
+ {
+ try
+ {
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
++
+ if (_dictSizeLog >= sizeof(size_t) * 8)
+ return E_NOTIMPL;
+
+diff --git a/CPP/7zip/Compress/Rar5Decoder.h b/CPP/7zip/Compress/Rar5Decoder.h
+index b0a4dd1..3db5018 100644
+--- a/CPP/7zip/Compress/Rar5Decoder.h
++++ b/CPP/7zip/Compress/Rar5Decoder.h
+@@ -271,6 +271,7 @@ class CDecoder:
+ Byte _dictSizeLog;
+ bool _tableWasFilled;
+ bool _isSolid;
++ bool _solidAllowed;
+ bool _wasInit;
+
+ 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 @@
+From: Robert Luberda <robert@debian.org>
+Date: Sun, 28 Jan 2018 23:47:40 +0100
+Subject: CVE-2018-5996
+
+Hopefully fix Memory Corruptions via RAR PPMd (CVE-2018-5996) by
+applying a few changes from 7Zip 18.00-beta.
+
+Bug-Debian: https://bugs.debian.org/#888314
+---
+ CPP/7zip/Compress/Rar1Decoder.cpp | 13 +++++++++----
+ CPP/7zip/Compress/Rar1Decoder.h | 1 +
+ CPP/7zip/Compress/Rar2Decoder.cpp | 10 +++++++++-
+ CPP/7zip/Compress/Rar2Decoder.h | 1 +
+ CPP/7zip/Compress/Rar3Decoder.cpp | 23 ++++++++++++++++++++---
+ CPP/7zip/Compress/Rar3Decoder.h | 2 ++
+ 6 files changed, 42 insertions(+), 8 deletions(-)
+
+diff --git a/CPP/7zip/Compress/Rar1Decoder.cpp b/CPP/7zip/Compress/Rar1Decoder.cpp
+index 1aaedcc..68030c7 100644
+--- a/CPP/7zip/Compress/Rar1Decoder.cpp
++++ b/CPP/7zip/Compress/Rar1Decoder.cpp
+@@ -29,7 +29,7 @@ public:
+ };
+ */
+
+-CDecoder::CDecoder(): m_IsSolid(false) { }
++CDecoder::CDecoder(): m_IsSolid(false), _errorMode(false) { }
+
+ void CDecoder::InitStructures()
+ {
+@@ -406,9 +406,14 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ InitData();
+ if (!m_IsSolid)
+ {
++ _errorMode = false;
+ InitStructures();
+ InitHuff();
+ }
++
++ if (_errorMode)
++ return S_FALSE;
++
+ if (m_UnpackSize > 0)
+ {
+ GetFlagsBuf();
+@@ -477,9 +482,9 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
+ {
+ try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
+- catch(const CInBufferException &e) { return e.ErrorCode; }
+- catch(const CLzOutWindowException &e) { return e.ErrorCode; }
+- catch(...) { return S_FALSE; }
++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
++ catch(const CLzOutWindowException &e) { _errorMode = true; return e.ErrorCode; }
++ catch(...) { _errorMode = true; return S_FALSE; }
+ }
+
+ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)
+diff --git a/CPP/7zip/Compress/Rar1Decoder.h b/CPP/7zip/Compress/Rar1Decoder.h
+index 630f089..01b606b 100644
+--- a/CPP/7zip/Compress/Rar1Decoder.h
++++ b/CPP/7zip/Compress/Rar1Decoder.h
+@@ -39,6 +39,7 @@ public:
+
+ Int64 m_UnpackSize;
+ bool m_IsSolid;
++ bool _errorMode;
+
+ UInt32 ReadBits(int numBits);
+ HRESULT CopyBlock(UInt32 distance, UInt32 len);
+diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp
+index b3f2b4b..0580c8d 100644
+--- a/CPP/7zip/Compress/Rar2Decoder.cpp
++++ b/CPP/7zip/Compress/Rar2Decoder.cpp
+@@ -80,7 +80,8 @@ static const UInt32 kHistorySize = 1 << 20;
+ static const UInt32 kWindowReservSize = (1 << 22) + 256;
+
+ CDecoder::CDecoder():
+- m_IsSolid(false)
++ m_IsSolid(false),
++ m_TablesOK(false)
+ {
+ }
+
+@@ -100,6 +101,8 @@ UInt32 CDecoder::ReadBits(unsigned numBits) { return m_InBitStream.ReadBits(numB
+
+ bool CDecoder::ReadTables(void)
+ {
++ m_TablesOK = false;
++
+ Byte levelLevels[kLevelTableSize];
+ Byte newLevels[kMaxTableSize];
+ m_AudioMode = (ReadBits(1) == 1);
+@@ -170,6 +173,8 @@ bool CDecoder::ReadTables(void)
+ }
+
+ memcpy(m_LastLevels, newLevels, kMaxTableSize);
++ m_TablesOK = true;
++
+ return true;
+ }
+
+@@ -344,6 +349,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
+ return S_FALSE;
+ }
+
++ if (!m_TablesOK)
++ return S_FALSE;
++
+ UInt64 startPos = m_OutWindowStream.GetProcessedSize();
+ while (pos < unPackSize)
+ {
+diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h
+index 3a0535c..0e9005f 100644
+--- a/CPP/7zip/Compress/Rar2Decoder.h
++++ b/CPP/7zip/Compress/Rar2Decoder.h
+@@ -139,6 +139,7 @@ class CDecoder :
+
+ UInt64 m_PackSize;
+ bool m_IsSolid;
++ bool m_TablesOK;
+
+ void InitStructures();
+ UInt32 ReadBits(unsigned numBits);
+diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
+index 3bf2513..6cb8a6a 100644
+--- a/CPP/7zip/Compress/Rar3Decoder.cpp
++++ b/CPP/7zip/Compress/Rar3Decoder.cpp
+@@ -92,7 +92,8 @@ CDecoder::CDecoder():
+ _writtenFileSize(0),
+ _vmData(0),
+ _vmCode(0),
+- m_IsSolid(false)
++ m_IsSolid(false),
++ _errorMode(false)
+ {
+ Ppmd7_Construct(&_ppmd);
+ }
+@@ -545,6 +546,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
+ return InitPPM();
+ }
+
++ TablesRead = false;
++ TablesOK = false;
++
+ _lzMode = true;
+ PrevAlignBits = 0;
+ PrevAlignCount = 0;
+@@ -606,6 +610,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
+ }
+ }
+ }
++ if (InputEofError())
++ return S_FALSE;
++
+ TablesRead = true;
+
+ // original code has check here:
+@@ -623,6 +630,9 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
+ RIF(m_LenDecoder.Build(&newLevels[kMainTableSize + kDistTableSize + kAlignTableSize]));
+
+ memcpy(m_LastLevels, newLevels, kTablesSizesSum);
++
++ TablesOK = true;
++
+ return S_OK;
+ }
+
+@@ -824,7 +834,12 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+ PpmEscChar = 2;
+ PpmError = true;
+ InitFilters();
++ _errorMode = false;
+ }
++
++ if (_errorMode)
++ return S_FALSE;
++
+ if (!m_IsSolid || !TablesRead)
+ {
+ bool keepDecompressing;
+@@ -838,6 +853,8 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
+ bool keepDecompressing;
+ if (_lzMode)
+ {
++ if (!TablesOK)
++ return S_FALSE;
+ RINOK(DecodeLZ(keepDecompressing))
+ }
+ else
+@@ -901,8 +918,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
+ _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
+ return CodeReal(progress);
+ }
+- catch(const CInBufferException &e) { return e.ErrorCode; }
+- catch(...) { return S_FALSE; }
++ catch(const CInBufferException &e) { _errorMode = true; return e.ErrorCode; }
++ catch(...) { _errorMode = true; return S_FALSE; }
+ // CNewException is possible here. But probably CNewException is caused
+ // by error in data stream.
+ }
+diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h
+index c130cec..2f72d7d 100644
+--- a/CPP/7zip/Compress/Rar3Decoder.h
++++ b/CPP/7zip/Compress/Rar3Decoder.h
+@@ -192,6 +192,7 @@ class CDecoder:
+ UInt32 _lastFilter;
+
+ bool m_IsSolid;
++ bool _errorMode;
+
+ bool _lzMode;
+ bool _unsupportedFilter;
+@@ -200,6 +201,7 @@ class CDecoder:
+ UInt32 PrevAlignCount;
+
+ bool TablesRead;
++ bool TablesOK;
+
+ CPpmd7 _ppmd;
+ int PpmEscChar;