On 2018/06/19 05:15, Josh Grosse wrote:
> 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.
It's a bit tricky to review the code changes directly, can you send some
links/information for the CVE-2018-10115 ones like you have for the
CVE-2017-17969 one so we at least have a better idea of provenance?
Seems there is also CVE-2018-5996 which looks fairly nasty.
> 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;
> +