A patch for CVE-2018-10115 was posted May 8, no comments received.
https://marc.info/?l=openbsd-ports&m=152581494615299&w=2
A patch for CVE-2017-17969 has been added to the attached diff.
Index: Makefile
===================================================================
RCS file: /systems/cvs/ports/archivers/p7zip/Makefile,v
retrieving revision 1.44
diff -u -p -r1.44 Makefile
--- Makefile 9 Apr 2018 15:58:26 -0000 1.44
+++ Makefile 8 May 2018 19:57:34 -0000
@@ -4,8 +4,8 @@ COMMENT-main= file archiver with high co
COMMENT-rar= rar modules for p7zip
V= 16.02
-REVISION-main= 4
-REVISION-rar= 1
+REVISION-main= 5
+REVISION-rar= 2
DISTNAME= p7zip_${V}_src_all
PKGNAME= p7zip-${V}
PKGNAME-main= p7zip-${V}
Index: patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_cpp
diff -N patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_cpp 8 May 2018 19:45:54
-0000
@@ -0,0 +1,49 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Archive/Rar/Rar5Handler.cpp
+--- CPP/7zip/Archive/Rar/Rar5Handler.cpp.orig
++++ CPP/7zip/Archive/Rar/Rar5Handler.cpp
+@@ -102,11 +102,11 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSi
+ {
+ *val = 0;
+
+- for (unsigned i = 0; i < maxSize;)
++ for (unsigned i = 0; i < maxSize && i < 10;)
+ {
+ Byte b = p[i];
+- if (i < 10)
+- *val |= (UInt64)(b & 0x7F) << (7 * i++);
++ *val |= (UInt64)(b & 0x7F) << (7 * i);
++ i++;
+ if ((b & 0x80) == 0)
+ return i;
+ }
+@@ -1182,6 +1182,7 @@ static const Byte kProps[] =
+ kpidSymLink,
+ kpidHardLink,
+ kpidCopyLink,
++ kpidVolumeIndex
+ };
+
+
+@@ -1601,6 +1602,18 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPI
+
+ case kpidSplitBefore: prop = item.IsSplitBefore(); break;
+ case kpidSplitAfter: prop = lastItem.IsSplitAfter(); break;
++
++ case kpidVolumeIndex:
++ {
++ if (item.VolIndex < _arcs.Size())
++ {
++ const CInArcInfo &arcInfo = _arcs[item.VolIndex].Info;
++ if (arcInfo.IsVolume())
++ prop = (UInt64)arcInfo.GetVolIndex();
++ }
++ break;
++ }
++
+ case kpidCRC:
+ {
+ const CItem *item2 = (lastItem.IsSplitAfter() ? &item : &lastItem);
Index: patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_h
===================================================================
RCS file: patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_h
diff -N patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Archive_Rar_Rar5Handler_h 8 May 2018 19:46:51
-0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Archive/Rar/Rar5Handler.h
+--- CPP/7zip/Archive/Rar/Rar5Handler.h.orig
++++ CPP/7zip/Archive/Rar/Rar5Handler.h
+@@ -168,7 +168,7 @@ struct CItem
+
+ AString Name;
+
+- int VolIndex;
++ unsigned VolIndex;
+ int NextItem;
+
+ UInt32 UnixMTime;
Index: patches/patch-CPP_7zip_Archive_Rar_RarHandler_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Archive_Rar_RarHandler_cpp
diff -N patches/patch-CPP_7zip_Archive_Rar_RarHandler_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Archive_Rar_RarHandler_cpp 8 May 2018 19:46:59
-0000
@@ -0,0 +1,30 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Archive/Rar/RarHandler.cpp
+--- CPP/7zip/Archive/Rar/RarHandler.cpp.orig
++++ CPP/7zip/Archive/Rar/RarHandler.cpp
+@@ -768,7 +768,8 @@ static const Byte kProps[] =
+ kpidCRC,
+ kpidHostOS,
+ kpidMethod,
+- kpidUnpackVer
++ kpidUnpackVer,
++ kpidVolumeIndex
+ };
+
+ static const Byte kArcProps[] =
+@@ -989,6 +990,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPI
+ case kpidCommented: prop = item.IsCommented(); break;
+ case kpidSplitBefore: prop = item.IsSplitBefore(); break;
+ case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems -
1].IsSplitAfter(); break;
++
++ case kpidVolumeIndex:
++ if (_arcInfo.Is_VolNumber_Defined())
++ prop = (UInt32)(_arcInfo.VolNumber + refItem.VolumeIndex);
++ break;
++
+ case kpidCRC:
+ {
+ prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
Index: patches/patch-CPP_7zip_Archive_Rar_RarHandler_h
===================================================================
RCS file: patches/patch-CPP_7zip_Archive_Rar_RarHandler_h
diff -N patches/patch-CPP_7zip_Archive_Rar_RarHandler_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Archive_Rar_RarHandler_h 8 May 2018 19:47:06
-0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Archive/Rar/RarHandler.h
+--- CPP/7zip/Archive/Rar/RarHandler.h.orig
++++ CPP/7zip/Archive/Rar/RarHandler.h
+@@ -26,7 +26,7 @@ struct CInArcInfo
+ UInt32 DataCRC;
+ bool EndOfArchive_was_Read;
+
+- CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false) {}
++ CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false), VolNumber(0) {}
+
+ UInt64 GetPhySize() const { return EndPos - StartPos; }
+
Index: patches/patch-CPP_7zip_Compress_Rar1Decoder_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar1Decoder_cpp
diff -N patches/patch-CPP_7zip_Compress_Rar1Decoder_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar1Decoder_cpp 8 May 2018 19:47:23
-0000
@@ -0,0 +1,666 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar1Decoder.cpp
+--- CPP/7zip/Compress/Rar1Decoder.cpp.orig
++++ CPP/7zip/Compress/Rar1Decoder.cpp
+@@ -1,7 +1,7 @@
+ // Rar1Decoder.cpp
+ // According to unRAR license, this code may not be used to develop
+ // a program that creates RAR archives
+-
++
+ #include "StdAfx.h"
+
+ #include "Rar1Decoder.h"
+@@ -9,77 +9,83 @@
+ namespace NCompress {
+ namespace NRar1 {
+
+-static const UInt32 PosL1[] = {0,0,0,2,3,5,7,11,16,20,24,32,32, 256};
+-static const UInt32 PosL2[] = {0,0,0,0,5,7,9,13,18,22,26,34,36, 256};
+-static const UInt32 PosHf0[] = {0,0,0,0,0,8,16,24,33,33,33,33,33, 257};
+-static const UInt32 PosHf1[] = {0,0,0,0,0,0,4,44,60,76,80,80,127, 257};
+-static const UInt32 PosHf2[] = {0,0,0,0,0,0,2,7,53,117,233, 257,0};
+-static const UInt32 PosHf3[] = {0,0,0,0,0,0,0,2,16,218,251, 257,0};
+-static const UInt32 PosHf4[] = {0,0,0,0,0,0,0,0,0,255, 257,0,0};
++static const unsigned kNumBits = 12;
+
+-static const UInt32 kHistorySize = (1 << 16);
++static const Byte kShortLen1[16 * 3] =
++{
++ 0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
++ 1,3,4,4,5,6,7,8,8,4,4,5,6,6,0,0,
++ 1,4,4,4,5,6,7,8,8,4,4,5,6,6,4,0
++};
+
+-/*
+-class CCoderReleaser
++static const Byte kShortLen2[16 * 3] =
+ {
+- CDecoder *m_Coder;
+-public:
+- CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+- ~CCoderReleaser() { m_Coder->ReleaseStreams(); }
++ 0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0,0,
++ 2,3,3,3,4,4,5,6,6,4,4,5,6,6,0,0,
++ 2,3,3,4,4,4,5,6,6,4,4,5,6,6,4,0
+ };
+-*/
+
+-CDecoder::CDecoder(): m_IsSolid(false) { }
++static const Byte PosL1[kNumBits + 1] = { 0,0,2,1,2,2,4,5,4,4,8,0,224 };
++static const Byte PosL2[kNumBits + 1] = { 0,0,0,5,2,2,4,5,4,4,8,2,220 };
+
+-void CDecoder::InitStructures()
+-{
+- for (int i = 0; i < kNumRepDists; i++)
+- m_RepDists[i] = 0;
+- m_RepDistPtr = 0;
+- LastLength = 0;
+- LastDist = 0;
+-}
++static const Byte PosHf0[kNumBits + 1] = { 0,0,0,0,8,8,8,9,0,0,0,0,224 };
++static const Byte PosHf1[kNumBits + 1] = { 0,0,0,0,0,4,40,16,16,4,0,47,130 };
++static const Byte PosHf2[kNumBits + 1] = { 0,0,0,0,0,2,5,46,64,116,24,0,0 };
++static const Byte PosHf3[kNumBits + 1] = { 0,0,0,0,0,0,2,14,202,33,6,0,0 };
++static const Byte PosHf4[kNumBits + 1] = { 0,0,0,0,0,0,0,0,255,2,0,0,0 };
+
+-UInt32 CDecoder::ReadBits(int numBits) { return
m_InBitStream.ReadBits(numBits); }
++static const UInt32 kHistorySize = (1 << 16);
+
++CDecoder::CDecoder():
++ _isSolid(false),
++ _solidAllowed(false)
++ { }
++
++UInt32 CDecoder::ReadBits(unsigned numBits) { return
m_InBitStream.ReadBits(numBits); }
++
+ HRESULT CDecoder::CopyBlock(UInt32 distance, UInt32 len)
+ {
+ if (len == 0)
+ return S_FALSE;
++ if (m_UnpackSize < len)
++ return S_FALSE;
+ m_UnpackSize -= len;
+ return m_OutWindowStream.CopyBlock(distance, len) ? S_OK : S_FALSE;
+ }
+
+-
+-UInt32 CDecoder::DecodeNum(const UInt32 *posTab)
++UInt32 CDecoder::DecodeNum(const Byte *numTab)
+ {
+- UInt32 startPos = 2;
+- UInt32 num = m_InBitStream.GetValue(12);
++ /*
++ {
++ // we can check that tables are correct
++ UInt32 sum = 0;
++ for (unsigned i = 0; i <= kNumBits; i++)
++ sum += ((UInt32)numTab[i] << (kNumBits - i));
++ if (sum != (1 << kNumBits))
++ throw 111;
++ }
++ */
++
++ UInt32 val = m_InBitStream.GetValue(kNumBits);
++ UInt32 sum = 0;
++ unsigned i = 2;
++
+ for (;;)
+ {
+- UInt32 cur = (posTab[startPos + 1] - posTab[startPos]) << (12 - startPos);
+- if (num < cur)
++ UInt32 num = numTab[i];
++ UInt32 cur = num << (kNumBits - i);
++ if (val < cur)
+ break;
+- startPos++;
+- num -= cur;
++ i++;
++ val -= cur;
++ sum += num;
+ }
+- m_InBitStream.MovePos(startPos);
+- return((num >> (12 - startPos)) + posTab[startPos]);
++ m_InBitStream.MovePos(i);
++ return ((val >> (kNumBits - i)) + sum);
+ }
+
+-static const Byte kShortLen1 [] = {1,3,4,4,5,6,7,8,8,4,4,5,6,6 };
+-static const Byte kShortLen1a[] = {1,4,4,4,5,6,7,8,8,4,4,5,6,6,4 };
+-static const Byte kShortLen2 [] = {2,3,3,3,4,4,5,6,6,4,4,5,6,6 };
+-static const Byte kShortLen2a[] = {2,3,3,4,4,4,5,6,6,4,4,5,6,6,4 };
+-static const UInt32 kShortXor1[] =
{0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+-static const UInt32 kShortXor2[] =
{0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
+-
+ HRESULT CDecoder::ShortLZ()
+ {
+- UInt32 len, saveLen, dist;
+- int distancePlace;
+- const Byte *kShortLen;
+- const UInt32 *kShortXor;
+ NumHuf = 0;
+
+ if (LCount == 2)
+@@ -91,20 +97,14 @@ HRESULT CDecoder::ShortLZ()
+
+ UInt32 bitField = m_InBitStream.GetValue(8);
+
+- if (AvrLn1 < 37)
++ UInt32 len, dist;
+ {
+- kShortLen = Buf60 ? kShortLen1a : kShortLen1;
+- kShortXor = kShortXor1;
++ const Byte *xors = (AvrLn1 < 37) ? kShortLen1 : kShortLen2;
++ const Byte *lens = xors + 16 + Buf60;
++ for (len = 0; ((bitField ^ xors[len]) >> (8 - lens[len])) != 0; len++);
++ m_InBitStream.MovePos(lens[len]);
+ }
+- else
+- {
+- kShortLen = Buf60 ? kShortLen2a : kShortLen2;
+- kShortXor = kShortXor2;
+- }
+
+- for (len = 0; ((bitField ^ kShortXor[len]) & (~(0xff >> kShortLen[len])))
!= 0; len++);
+- m_InBitStream.MovePos(kShortLen[len]);
+-
+ if (len >= 9)
+ {
+ if (len == 9)
+@@ -112,9 +112,11 @@ HRESULT CDecoder::ShortLZ()
+ LCount++;
+ return CopyBlock(LastDist, LastLength);
+ }
++
++ LCount = 0;
++
+ if (len == 14)
+ {
+- LCount = 0;
+ len = DecodeNum(PosL2) + 5;
+ dist = 0x8000 + ReadBits(15) - 1;
+ LastLength = len;
+@@ -122,41 +124,46 @@ HRESULT CDecoder::ShortLZ()
+ return CopyBlock(dist, len);
+ }
+
+- LCount = 0;
+- saveLen = len;
++ UInt32 saveLen = len;
+ dist = m_RepDists[(m_RepDistPtr - (len - 9)) & 3];
+- len = DecodeNum(PosL1) + 2;
+- if (len == 0x101 && saveLen == 10)
++
++ len = DecodeNum(PosL1);
++
++ if (len == 0xff && saveLen == 10)
+ {
+- Buf60 ^= 1;
++ Buf60 ^= 16;
+ return S_OK;
+ }
+ if (dist >= 256)
++ {
+ len++;
+- if (dist >= MaxDist3 - 1)
+- len++;
++ if (dist >= MaxDist3 - 1)
++ len++;
++ }
+ }
+ else
+ {
+ LCount = 0;
+ AvrLn1 += len;
+ AvrLn1 -= AvrLn1 >> 4;
+-
+- distancePlace = DecodeNum(PosHf2) & 0xff;
+- dist = ChSetA[(unsigned)distancePlace];
+- if (--distancePlace != -1)
++
++ unsigned distancePlace = DecodeNum(PosHf2) & 0xff;
++
++ dist = ChSetA[distancePlace];
++
++ if (distancePlace != 0)
+ {
+ PlaceA[dist]--;
+- UInt32 lastDistance = ChSetA[(unsigned)distancePlace];
++ UInt32 lastDistance = ChSetA[(size_t)distancePlace - 1];
+ PlaceA[lastDistance]++;
+- ChSetA[(unsigned)distancePlace + 1] = lastDistance;
+- ChSetA[(unsigned)distancePlace] = dist;
++ ChSetA[distancePlace] = lastDistance;
++ ChSetA[(size_t)distancePlace - 1] = dist;
+ }
+- len += 2;
+ }
+
+ m_RepDists[m_RepDistPtr++] = dist;
+ m_RepDistPtr &= 3;
++ len += 2;
+ LastLength = len;
+ LastDist = dist;
+ return CopyBlock(dist, len);
+@@ -177,12 +184,10 @@ HRESULT CDecoder::LongLZ()
+ Nlzb = 0x90;
+ Nhfb >>= 1;
+ }
+- oldAvr2=AvrLn2;
++ oldAvr2 = AvrLn2;
+
+- if (AvrLn2 >= 122)
+- len = DecodeNum(PosL2);
+- else if (AvrLn2 >= 64)
+- len = DecodeNum(PosL1);
++ if (AvrLn2 >= 64)
++ len = DecodeNum(AvrLn2 < 122 ? PosL1 : PosL2);
+ else
+ {
+ UInt32 bitField = m_InBitStream.GetValue(16);
+@@ -193,8 +198,8 @@ HRESULT CDecoder::LongLZ()
+ }
+ else
+ {
+- for (len = 0; ((bitField << len) & 0x8000) == 0; len++)
+- ;
++ for (len = 0; ((bitField << len) & 0x8000) == 0; len++);
++
+ m_InBitStream.MovePos(len + 1);
+ }
+ }
+@@ -202,24 +207,25 @@ HRESULT CDecoder::LongLZ()
+ AvrLn2 += len;
+ AvrLn2 -= AvrLn2 >> 5;
+
+- if (AvrPlcB > 0x28ff)
+- distancePlace = DecodeNum(PosHf2);
+- else if (AvrPlcB > 0x6ff)
+- distancePlace = DecodeNum(PosHf1);
+- else
+- distancePlace = DecodeNum(PosHf0);
+-
++ {
++ const Byte *tab;
++ if (AvrPlcB >= 0x2900) tab = PosHf2;
++ else if (AvrPlcB >= 0x0700) tab = PosHf1;
++ else tab = PosHf0;
++ distancePlace = DecodeNum(tab); // [0, 256]
++ }
+ AvrPlcB += distancePlace;
+ AvrPlcB -= AvrPlcB >> 8;
+-
++
++ distancePlace &= 0xff;
++
+ for (;;)
+ {
+- dist = ChSetB[distancePlace & 0xff];
++ dist = ChSetB[distancePlace];
+ newDistancePlace = NToPlB[dist++ & 0xff]++;
+- if (!(dist & 0xff))
+- CorrHuff(ChSetB,NToPlB);
+- else
++ if (dist & 0xff)
+ break;
++ CorrHuff(ChSetB,NToPlB);
+ }
+
+ ChSetB[distancePlace] = ChSetB[newDistancePlace];
+@@ -228,34 +234,33 @@ HRESULT CDecoder::LongLZ()
+ dist = ((dist & 0xff00) >> 1) | ReadBits(7);
+
+ oldAvr3 = AvrLn3;
+-
++
+ if (len != 1 && len != 4)
+ if (len == 0 && dist <= MaxDist3)
+ {
+ AvrLn3++;
+ AvrLn3 -= AvrLn3 >> 8;
+ }
+- else
+- if (AvrLn3 > 0)
++ else if (AvrLn3 > 0)
+ AvrLn3--;
+-
++
+ len += 3;
+-
++
+ if (dist >= MaxDist3)
+ len++;
+ if (dist <= 256)
+ len += 8;
+-
++
+ if (oldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && oldAvr2 < 0x40)
+ MaxDist3 = 0x7f00;
+ else
+ MaxDist3 = 0x2001;
+-
++
+ m_RepDists[m_RepDistPtr++] = --dist;
+ m_RepDistPtr &= 3;
+ LastLength = len;
+ LastDist = dist;
+-
++
+ return CopyBlock(dist, len);
+ }
+
+@@ -265,57 +270,62 @@ HRESULT CDecoder::HuffDecode()
+ UInt32 curByte, newBytePlace;
+ UInt32 len;
+ UInt32 dist;
+- int bytePlace;
++ unsigned bytePlace;
++ {
++ const Byte *tab;
+
+- if (AvrPlc > 0x75ff) bytePlace = DecodeNum(PosHf4);
+- else if (AvrPlc > 0x5dff) bytePlace = DecodeNum(PosHf3);
+- else if (AvrPlc > 0x35ff) bytePlace = DecodeNum(PosHf2);
+- else if (AvrPlc > 0x0dff) bytePlace = DecodeNum(PosHf1);
+- else bytePlace = DecodeNum(PosHf0);
+-
++ if (AvrPlc >= 0x7600) tab = PosHf4;
++ else if (AvrPlc >= 0x5e00) tab = PosHf3;
++ else if (AvrPlc >= 0x3600) tab = PosHf2;
++ else if (AvrPlc >= 0x0e00) tab = PosHf1;
++ else tab = PosHf0;
++
++ bytePlace = DecodeNum(tab); // [0, 256]
++ } bytePlace = DecodeNum(PosHf0);
++
+ if (StMode)
+ {
+- if (--bytePlace == -1)
++ if (bytePlace == 0)
+ {
+ if (ReadBits(1))
+ {
+- NumHuf = StMode = 0;
++ NumHuf = 0;
++ StMode = false;
+ return S_OK;
+ }
+- else
+- {
+- len = (ReadBits(1)) ? 4 : 3;
+- dist = DecodeNum(PosHf2);
+- dist = (dist << 5) | ReadBits(5);
+- return CopyBlock(dist - 1, len);
+- }
++ len = ReadBits(1) + 3;
++ dist = DecodeNum(PosHf2);
++ dist = (dist << 5) | ReadBits(5);
++ if (dist == 0)
++ return S_FALSE;
++ return CopyBlock(dist - 1, len);
+ }
++ bytePlace--; // bytePlace is [0, 255]
+ }
+ else if (NumHuf++ >= 16 && FlagsCnt == 0)
+- StMode = 1;
+-
++ StMode = true;
++
+ bytePlace &= 0xff;
+ AvrPlc += bytePlace;
+ AvrPlc -= AvrPlc >> 8;
+- Nhfb+=16;
+-
++ Nhfb += 16;
++
+ if (Nhfb > 0xff)
+ {
+- Nhfb=0x90;
++ Nhfb = 0x90;
+ Nlzb >>= 1;
+ }
+
+- m_UnpackSize --;
++ m_UnpackSize--;
+ m_OutWindowStream.PutByte((Byte)(ChSet[bytePlace] >> 8));
+
+ for (;;)
+ {
+ curByte = ChSet[bytePlace];
+ newBytePlace = NToPl[curByte++ & 0xff]++;
+- if ((curByte & 0xff) > 0xa1)
+- CorrHuff(ChSet, NToPl);
+- else
++ if ((curByte & 0xff) <= 0xa1)
+ break;
++ CorrHuff(ChSet, NToPl);
+ }
+
+ ChSet[bytePlace] = ChSet[newBytePlace];
+@@ -327,8 +337,11 @@ HRESULT CDecoder::HuffDecode()
+ void CDecoder::GetFlagsBuf()
+ {
+ UInt32 flags, newFlagsPlace;
+- UInt32 flagsPlace = DecodeNum(PosHf2);
++ UInt32 flagsPlace = DecodeNum(PosHf2); // [0, 256]
+
++ if (flagsPlace >= ARRAY_SIZE(ChSetC))
++ return;
++
+ for (;;)
+ {
+ flags = ChSetC[flagsPlace];
+@@ -343,21 +356,6 @@ void CDecoder::GetFlagsBuf()
+ ChSetC[newFlagsPlace] = flags;
+ }
+
+-void CDecoder::InitData()
+-{
+- if (!m_IsSolid)
+- {
+- AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
+- AvrPlc = 0x3500;
+- MaxDist3 = 0x2001;
+- Nhfb = Nlzb = 0x80;
+- }
+- FlagsCnt = 0;
+- FlagBuf = 0;
+- StMode = 0;
+- LCount = 0;
+-}
+-
+ void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToPlace)
+ {
+ int i;
+@@ -369,81 +367,79 @@ void CDecoder::CorrHuff(UInt32 *CharSet,UInt32 *NumToP
+ NumToPlace[i] = (7 - i) * 32;
+ }
+
+-void CDecoder::InitHuff()
+-{
+- for (UInt32 i = 0; i < 256; i++)
+- {
+- Place[i] = PlaceA[i] = PlaceB[i] = i;
+- PlaceC[i] = (~i + 1) & 0xff;
+- ChSet[i] = ChSetB[i] = i << 8;
+- ChSetA[i] = i;
+- ChSetC[i] = ((~i + 1) & 0xff) << 8;
+- }
+- memset(NToPl, 0, sizeof(NToPl));
+- memset(NToPlB, 0, sizeof(NToPlB));
+- memset(NToPlC, 0, sizeof(NToPlC));
+- CorrHuff(ChSetB, NToPlB);
+-}
+-
+ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo * /*
progress */)
+ {
+- if (inSize == NULL || outSize == NULL)
++ if (!inSize || !outSize)
+ 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))
+ return E_OUTOFMEMORY;
+
+- m_UnpackSize = (Int64)*outSize;
++ m_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);
+- InitData();
+- if (!m_IsSolid)
++ // InitData
++
++ FlagsCnt = 0;
++ FlagBuf = 0;
++ StMode = false;
++ LCount = 0;
++
++ if (!_isSolid)
+ {
+- InitStructures();
+- InitHuff();
++ AvrPlcB = AvrLn1 = AvrLn2 = AvrLn3 = NumHuf = Buf60 = 0;
++ AvrPlc = 0x3500;
++ MaxDist3 = 0x2001;
++ Nhfb = Nlzb = 0x80;
++
++ {
++ // InitStructures
++ for (int i = 0; i < kNumRepDists; i++)
++ m_RepDists[i] = 0;
++ m_RepDistPtr = 0;
++ LastLength = 0;
++ LastDist = 0;
++ }
++
++ // InitHuff
++
++ for (UInt32 i = 0; i < 256; i++)
++ {
++ Place[i] = PlaceA[i] = PlaceB[i] = i;
++ UInt32 c = (~i + 1) & 0xff;
++ PlaceC[i] = c;
++ ChSet[i] = ChSetB[i] = i << 8;
++ ChSetA[i] = i;
++ ChSetC[i] = c << 8;
++ }
++ memset(NToPl, 0, sizeof(NToPl));
++ memset(NToPlB, 0, sizeof(NToPlB));
++ memset(NToPlC, 0, sizeof(NToPlC));
++ CorrHuff(ChSetB, NToPlB);
+ }
++
+ if (m_UnpackSize > 0)
+ {
+ GetFlagsBuf();
+ FlagsCnt = 8;
+ }
+
+- while (m_UnpackSize > 0)
++ while (m_UnpackSize != 0)
+ {
+- if (StMode)
++ if (!StMode)
+ {
+- RINOK(HuffDecode());
+- continue;
+- }
+-
+- if (--FlagsCnt < 0)
+- {
+- GetFlagsBuf();
+- FlagsCnt=7;
+- }
+-
+- if (FlagBuf & 0x80)
+- {
+- FlagBuf <<= 1;
+- if (Nlzb > Nhfb)
+- {
+- RINOK(LongLZ());
+- }
+- else
+- {
+- RINOK(HuffDecode());
+- }
+- }
+- else
+- {
+- FlagBuf <<= 1;
+ if (--FlagsCnt < 0)
+ {
+ GetFlagsBuf();
+@@ -454,22 +450,41 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStre
+ FlagBuf <<= 1;
+ if (Nlzb > Nhfb)
+ {
+- RINOK(HuffDecode());
+- }
+- else
+- {
+ RINOK(LongLZ());
++ continue;
+ }
+ }
+ else
+ {
+ FlagBuf <<= 1;
+- RINOK(ShortLZ());
++
++ if (--FlagsCnt < 0)
++ {
++ GetFlagsBuf();
++ FlagsCnt = 7;
++ }
++
++ if ((FlagBuf & 0x80) == 0)
++ {
++ FlagBuf <<= 1;
++ RINOK(ShortLZ());
++ continue;
++ }
++
++ FlagBuf <<= 1;
++
++ if (Nlzb <= Nhfb)
++ {
++ RINOK(LongLZ());
++ continue;
++ }
+ }
+ }
++
++ RINOK(HuffDecode());
+ }
+- if (m_UnpackSize < 0)
+- return S_FALSE;
++
++ _solidAllowed = true;
+ return m_OutWindowStream.Flush();
+ }
+
+@@ -486,7 +501,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byt
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
Index: patches/patch-CPP_7zip_Compress_Rar1Decoder_h
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar1Decoder_h
diff -N patches/patch-CPP_7zip_Compress_Rar1Decoder_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar1Decoder_h 8 May 2018 19:47:28
-0000
@@ -0,0 +1,90 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar1Decoder.h
+--- CPP/7zip/Compress/Rar1Decoder.h.orig
++++ CPP/7zip/Compress/Rar1Decoder.h
+@@ -20,48 +20,45 @@ namespace NRar1 {
+
+ const UInt32 kNumRepDists = 4;
+
+-typedef NBitm::CDecoder<CInBuffer> CBitDecoder;
+-
+ class CDecoder :
+ public ICompressCoder,
+ public ICompressSetDecoderProperties2,
+ public CMyUnknownImp
+ {
+-public:
+ CLzOutWindow m_OutWindowStream;
+- CBitDecoder m_InBitStream;
++ NBitm::CDecoder<CInBuffer> m_InBitStream;
+
+- UInt32 m_RepDists[kNumRepDists];
+- UInt32 m_RepDistPtr;
++ UInt64 m_UnpackSize;
+
+ UInt32 LastDist;
+ UInt32 LastLength;
+
+- Int64 m_UnpackSize;
+- bool m_IsSolid;
++ UInt32 m_RepDistPtr;
++ UInt32 m_RepDists[kNumRepDists];
+
+- UInt32 ReadBits(int numBits);
+- HRESULT CopyBlock(UInt32 distance, UInt32 len);
++ bool _isSolid;
++ bool _solidAllowed;
+
+- UInt32 DecodeNum(const UInt32 *posTab);
++ bool StMode;
++ int FlagsCnt;
++ UInt32 FlagBuf, AvrPlc, AvrPlcB, AvrLn1, AvrLn2, AvrLn3;
++ unsigned Buf60, NumHuf, LCount;
++ UInt32 Nhfb, Nlzb, MaxDist3;
++
++ UInt32 ChSet[256], ChSetA[256], ChSetB[256], ChSetC[256];
++ UInt32 Place[256], PlaceA[256], PlaceB[256], PlaceC[256];
++ UInt32 NToPl[256], NToPlB[256], NToPlC[256];
++
++ UInt32 ReadBits(unsigned numBits);
++ HRESULT CopyBlock(UInt32 distance, UInt32 len);
++ UInt32 DecodeNum(const Byte *numTab);
+ HRESULT ShortLZ();
+ HRESULT LongLZ();
+ HRESULT HuffDecode();
+ void GetFlagsBuf();
+- void InitData();
+- void InitHuff();
+ void CorrHuff(UInt32 *CharSet, UInt32 *NumToPlace);
+ void OldUnpWriteBuf();
+
+- UInt32 ChSet[256],ChSetA[256],ChSetB[256],ChSetC[256];
+- UInt32 Place[256],PlaceA[256],PlaceB[256],PlaceC[256];
+- UInt32 NToPl[256],NToPlB[256],NToPlC[256];
+- UInt32 FlagBuf,AvrPlc,AvrPlcB,AvrLn1,AvrLn2,AvrLn3;
+- int Buf60,NumHuf,StMode,LCount,FlagsCnt;
+- UInt32 Nhfb,Nlzb,MaxDist3;
+-
+- void InitStructures();
+-
+ HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream
*outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo
*progress);
+
+@@ -69,14 +66,6 @@ class CDecoder : (public)
+ CDecoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+-
+- /*
+- void ReleaseStreams()
+- {
+- m_OutWindowStream.ReleaseStream();
+- m_InBitStream.ReleaseStream();
+- }
+- */
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream
*outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo
*progress);
Index: patches/patch-CPP_7zip_Compress_Rar2Decoder_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar2Decoder_cpp
diff -N patches/patch-CPP_7zip_Compress_Rar2Decoder_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar2Decoder_cpp 8 May 2018 19:47:32
-0000
@@ -0,0 +1,94 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar2Decoder.cpp
+--- CPP/7zip/Compress/Rar2Decoder.cpp.orig
++++ 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)
+ {
+ }
+
+@@ -199,19 +200,6 @@ bool CDecoder::ReadLastTables()
+ return true;
+ }
+
+-/*
+-class CCoderReleaser
+-{
+- CDecoder *m_Coder;
+-public:
+- CCoderReleaser(CDecoder *coder): m_Coder(coder) {}
+- ~CCoderReleaser()
+- {
+- m_Coder->ReleaseStreams();
+- }
+-};
+-*/
+-
+ bool CDecoder::DecodeMm(UInt32 pos)
+ {
+ while (pos-- > 0)
+@@ -312,8 +300,12 @@ bool CDecoder::DecodeLz(Int32 pos)
+ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo
*progress)
+ {
+- if (inSize == NULL || outSize == NULL)
+- return E_INVALIDARG;
++ if (!inSize || !outSize)
++ return E_INVALIDARG;
++
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
+
+ if (!m_OutWindowStream.Create(kHistorySize))
+ return E_OUTOFMEMORY;
+@@ -325,12 +317,12 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStre
+ 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)
+@@ -338,6 +330,7 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStre
+ if (m_InBitStream.GetProcessedSize() + 2 <= m_PackSize) // test it:
probably incorrect;
+ if (!ReadTables())
+ return S_FALSE;
++ _solidAllowed = true;
+ return S_OK;
+ }
+ if (!ReadTables())
+@@ -378,6 +371,9 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStre
+
+ if (!ReadLastTables())
+ return S_FALSE;
++
++ _solidAllowed = true;
++
+ return m_OutWindowStream.Flush();
+ }
+
+@@ -394,7 +390,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byt
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
Index: patches/patch-CPP_7zip_Compress_Rar2Decoder_h
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar2Decoder_h
diff -N patches/patch-CPP_7zip_Compress_Rar2Decoder_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar2Decoder_h 8 May 2018 19:47:47
-0000
@@ -0,0 +1,32 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar2Decoder.h
+--- CPP/7zip/Compress/Rar2Decoder.h.orig
++++ 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;
+
+ void InitStructures();
+ UInt32 ReadBits(unsigned numBits);
+@@ -155,14 +156,6 @@ class CDecoder :
+ CDecoder();
+
+ MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
+-
+- /*
+- void ReleaseStreams()
+- {
+- m_OutWindowStream.ReleaseStream();
+- m_InBitStream.ReleaseStream();
+- }
+- */
+
+ STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream
*outStream,
+ const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo
*progress);
Index: patches/patch-CPP_7zip_Compress_Rar3Decoder_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar3Decoder_cpp
diff -N patches/patch-CPP_7zip_Compress_Rar3Decoder_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar3Decoder_cpp 8 May 2018 19:47:52
-0000
@@ -0,0 +1,85 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar3Decoder.cpp
+--- CPP/7zip/Compress/Rar3Decoder.cpp.orig
++++ CPP/7zip/Compress/Rar3Decoder.cpp
+@@ -92,7 +92,8 @@ CDecoder::CDecoder():
+ _writtenFileSize(0),
+ _vmData(0),
+ _vmCode(0),
+- m_IsSolid(false)
++ _isSolid(false),
++ _solidAllowed(false)
+ {
+ Ppmd7_Construct(&_ppmd);
+ }
+@@ -811,7 +812,7 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *prog
+ {
+ _writtenFileSize = 0;
+ _unsupportedFilter = false;
+- if (!m_IsSolid)
++ if (!_isSolid)
+ {
+ _lzSize = 0;
+ _winPos = 0;
+@@ -825,12 +826,15 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *prog
+ PpmError = true;
+ InitFilters();
+ }
+- if (!m_IsSolid || !TablesRead)
++ if (!_isSolid || !TablesRead)
+ {
+ bool keepDecompressing;
+ RINOK(ReadTables(keepDecompressing));
+ if (!keepDecompressing)
+- return S_OK;
++ {
++ _solidAllowed = true;
++ return S_OK;
++ }
+ }
+
+ for (;;)
+@@ -853,6 +857,9 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *prog
+ if (!keepDecompressing)
+ break;
+ }
++
++ _solidAllowed = true;
++
+ RINOK(WriteBuf());
+ UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
+ RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
+@@ -873,6 +880,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStr
+ if (!inSize)
+ return E_INVALIDARG;
+
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
++
+ if (!_vmData)
+ {
+ _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
+@@ -901,8 +912,8 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStr
+ _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.
+ }
+@@ -911,7 +922,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byt
+ {
+ if (size < 1)
+ return E_INVALIDARG;
+- m_IsSolid = ((data[0] & 1) != 0);
++ _isSolid = ((data[0] & 1) != 0);
+ return S_OK;
+ }
+
Index: patches/patch-CPP_7zip_Compress_Rar3Decoder_h
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar3Decoder_h
diff -N patches/patch-CPP_7zip_Compress_Rar3Decoder_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar3Decoder_h 8 May 2018 19:47:56
-0000
@@ -0,0 +1,18 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar3Decoder.h
+--- CPP/7zip/Compress/Rar3Decoder.h.orig
++++ CPP/7zip/Compress/Rar3Decoder.h
+@@ -191,7 +191,9 @@ class CDecoder:
+ CRecordVector<CTempFilter *> _tempFilters;
+ UInt32 _lastFilter;
+
+- bool m_IsSolid;
++ bool _isSolid;
++ bool _solidAllowed;
++ // bool _errorMode;
+
+ bool _lzMode;
+ bool _unsupportedFilter;
Index: patches/patch-CPP_7zip_Compress_Rar5Decoder_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar5Decoder_cpp
diff -N patches/patch-CPP_7zip_Compress_Rar5Decoder_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar5Decoder_cpp 8 May 2018 19:48:03
-0000
@@ -0,0 +1,149 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar5Decoder.cpp
+--- CPP/7zip/Compress/Rar5Decoder.cpp.orig
++++ CPP/7zip/Compress/Rar5Decoder.cpp
+@@ -72,6 +72,7 @@ CDecoder::CDecoder():
+ _writtenFileSize(0),
+ _dictSizeLog(0),
+ _isSolid(false),
++ _solidAllowed(false),
+ _wasInit(false),
+ _inputBuf(NULL)
+ {
+@@ -328,59 +329,63 @@ HRESULT CDecoder::ReadTables(CBitDecoder &_bitStream)
+ {
+ if (_progress)
+ {
+- UInt64 packSize = _bitStream.GetProcessedSize();
++ const UInt64 packSize = _bitStream.GetProcessedSize();
+ RINOK(_progress->SetRatioInfo(&packSize, &_writtenFileSize));
+ }
+
+ _bitStream.AlignToByte();
+ _bitStream.Prepare();
+
+- unsigned flags = _bitStream.ReadByteInAligned();
+- unsigned checkSum = _bitStream.ReadByteInAligned();
+- checkSum ^= flags;
+-
+- UInt32 blockSize;
+ {
++ unsigned flags = _bitStream.ReadByteInAligned();
++ unsigned checkSum = _bitStream.ReadByteInAligned();
++ checkSum ^= flags;
+ unsigned num = (flags >> 3) & 3;
+ if (num == 3)
+ return S_FALSE;
+- blockSize = _bitStream.ReadByteInAligned();
+- if (num > 0)
++ UInt32 blockSize = _bitStream.ReadByteInAligned();
++ checkSum ^= blockSize;
++
++ if (num != 0)
+ {
+- blockSize += (UInt32)_bitStream.ReadByteInAligned() << 8;
++ unsigned b = _bitStream.ReadByteInAligned();
++ checkSum ^= b;
++ blockSize += (UInt32)b << 8;
+ if (num > 1)
+- blockSize += (UInt32)_bitStream.ReadByteInAligned() << 16;
++ {
++ b = _bitStream.ReadByteInAligned();
++ checkSum ^= b;
++ blockSize += (UInt32)b << 16;
++ }
+ }
+- }
+-
+- checkSum ^= blockSize ^ (blockSize >> 8) ^ (blockSize >> 16);
+- if ((Byte)checkSum != 0x5A)
+- return S_FALSE;
+-
+- unsigned blockSizeBits7 = (flags & 7) + 1;
+-
+- if (blockSize == 0 && blockSizeBits7 != 8)
+- return S_FALSE;
+-
+- blockSize += (blockSizeBits7 >> 3);
+- blockSize--;
+-
+- _bitStream._blockEndBits7 = (Byte)(blockSizeBits7 & 7);
+- _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize;
+-
+- _bitStream.SetCheck2();
+-
+- _isLastBlock = ((flags & 0x40) != 0);
+-
+- if ((flags & 0x80) == 0)
+- {
+- if (!_tableWasFilled && blockSize != 0)
++
++ if (checkSum != 0x5A)
+ return S_FALSE;
+- return S_OK;
++ unsigned blockSizeBits7 = (flags & 7) + 1;
++ blockSize += (blockSizeBits7 >> 3);
++ if (blockSize == 0)
++ return S_FALSE;
++ blockSize--;
++ blockSizeBits7 &= 7;
++
++ _bitStream._blockEndBits7 = (Byte)blockSizeBits7;
++ _bitStream._blockEnd = _bitStream.GetProcessedSize_Round() + blockSize;
++
++ _bitStream.SetCheck2();
++
++ _isLastBlock = ((flags & 0x40) != 0);
++
++ if ((flags & 0x80) == 0)
++ {
++ if (!_tableWasFilled)
++ if (blockSize != 0 || blockSizeBits7 != 0)
++ return S_FALSE;
++ return S_OK;
++ }
++
++ _tableWasFilled = false;
+ }
+
+- _tableWasFilled = false;
+-
+ {
+ Byte lens2[kLevelTableSize];
+
+@@ -600,6 +605,10 @@ HRESULT CDecoder::DecodeLZ()
+ }
+ }
+ }
++
++ // that check is not required, but it can help, if there is BUG in
another code
++ if (!_tableWasFilled)
++ break; // return S_FALSE;
+ }
+
+ UInt32 sym = m_MainDecoder.Decode(&_bitStream);
+@@ -801,7 +810,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 +833,10 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStr
+ {
+ try
+ {
++ if (_isSolid && !_solidAllowed)
++ return S_FALSE;
++ _solidAllowed = false;
++
+ if (_dictSizeLog >= sizeof(size_t) * 8)
+ return E_NOTIMPL;
+
Index: patches/patch-CPP_7zip_Compress_Rar5Decoder_h
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_Rar5Decoder_h
diff -N patches/patch-CPP_7zip_Compress_Rar5Decoder_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_Rar5Decoder_h 8 May 2018 19:48:09
-0000
@@ -0,0 +1,49 @@
+$OpenBSD$
+
+Fix for CVE-2018-10115, from Denisov Denis.
+
+Index: CPP/7zip/Compress/Rar5Decoder.h
+--- CPP/7zip/Compress/Rar5Decoder.h.orig
++++ CPP/7zip/Compress/Rar5Decoder.h
+@@ -157,7 +157,7 @@ class CBitDecoder (public)
+ return *_buf++;
+ }
+
+- UInt32 GetValue(unsigned numBits)
++ UInt32 GetValue(unsigned numBits) const
+ {
+ UInt32 v = ((UInt32)_buf[0] << 16) | ((UInt32)_buf[1] << 8) |
(UInt32)_buf[2];
+ v >>= (24 - numBits - _bitPos);
+@@ -249,11 +249,19 @@ class CDecoder:
+ bool _lzError;
+ bool _writeError;
+
++ bool _isSolid;
++ bool _solidAllowed;
++ bool _tableWasFilled;
++ bool _wasInit;
++
++ Byte _dictSizeLog;
++
+ // CBitDecoder _bitStream;
+ Byte *_window;
+ size_t _winPos;
+ size_t _winSize;
+ size_t _winMask;
++ size_t _winSizeAllocated;
+
+ UInt64 _lzSize;
+
+@@ -266,12 +274,6 @@ class CDecoder:
+ // UInt64 _packSize;
+ UInt64 _lzEnd;
+ UInt64 _writtenFileSize;
+- size_t _winSizeAllocated;
+-
+- Byte _dictSizeLog;
+- bool _tableWasFilled;
+- bool _isSolid;
+- bool _wasInit;
+
+ UInt32 _reps[kNumReps];
+ UInt32 _lastLen;
Index: patches/patch-CPP_7zip_Compress_ShrinkDecoder_cpp
===================================================================
RCS file: patches/patch-CPP_7zip_Compress_ShrinkDecoder_cpp
diff -N patches/patch-CPP_7zip_Compress_ShrinkDecoder_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-CPP_7zip_Compress_ShrinkDecoder_cpp 19 Jun 2018 09:06:08
-0000
@@ -0,0 +1,22 @@
+$OpenBSD$
+
+For CVE-2017-17969, from https://sourceforge.net/p/p7zip/bugs/204/
+
+Index: CPP/7zip/Compress/ShrinkDecoder.cpp
+--- CPP/7zip/Compress/ShrinkDecoder.cpp.orig
++++ CPP/7zip/Compress/ShrinkDecoder.cpp
+@@ -121,8 +121,13 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStre
+ {
+ _stack[i++] = _suffixes[cur];
+ cur = _parents[cur];
++ if (cur >= kNumItems || i >= kNumItems)
++ break;
+ }
+-
++
++ if (cur >= kNumItems || i >= kNumItems)
++ break;
++
+ _stack[i++] = (Byte)cur;
+ lastChar2 = (Byte)cur;
+