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;
+ 

Reply via email to