]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/Decompress.c
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / C / Common / Decompress.c
index 48578ea2f2d27bc0cca2ac08bcc993ed7844497f..d85098f1314050945140d4f7c785e208dd30ecaf 100644 (file)
@@ -1,20 +1,15 @@
 /** @file\r
-Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano \r
+Decompressor. Algorithm Ported from OPSD code (Decomp.asm) for Efi and Tiano\r
 compress algorithm.\r
 \r
-Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 --*/\r
 \r
 #include <stdlib.h>\r
 #include <string.h>\r
+#include <assert.h>\r
 #include "Decompress.h"\r
 \r
 //\r
@@ -88,11 +83,11 @@ Returns: (VOID)
 \r
 --*/\r
 {\r
-  Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);\r
+  Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);\r
 \r
   while (NumOfBits > Sd->mBitCount) {\r
 \r
-    Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
+    Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));\r
 \r
     if (Sd->mCompSize > 0) {\r
       //\r
@@ -193,12 +188,16 @@ Returns:
   UINT16  Avail;\r
   UINT16  NextCode;\r
   UINT16  Mask;\r
+  UINT16  MaxTableLength;\r
 \r
   for (Index = 1; Index <= 16; Index++) {\r
     Count[Index] = 0;\r
   }\r
 \r
   for (Index = 0; Index < NumOfChar; Index++) {\r
+    if (BitLen[Index] > 16) {\r
+      return (UINT16) BAD_TABLE;\r
+    }\r
     Count[BitLen[Index]]++;\r
   }\r
 \r
@@ -236,11 +235,12 @@ Returns:
 \r
   Avail = NumOfChar;\r
   Mask  = (UINT16) (1U << (15 - TableBits));\r
+  MaxTableLength = (UINT16) (1U << TableBits);\r
 \r
   for (Char = 0; Char < NumOfChar; Char++) {\r
 \r
     Len = BitLen[Char];\r
-    if (Len == 0) {\r
+    if (Len == 0 || Len >= 17) {\r
       continue;\r
     }\r
 \r
@@ -248,6 +248,10 @@ Returns:
 \r
     if (Len <= TableBits) {\r
 \r
+      if (Start[Len] >= NextCode || NextCode > MaxTableLength){\r
+        return (UINT16) BAD_TABLE;\r
+      }\r
+\r
       for (Index = Start[Len]; Index < NextCode; Index++) {\r
         Table[Index] = Char;\r
       }\r
@@ -373,6 +377,8 @@ Returns:
   UINT16  Index;\r
   UINT32  Mask;\r
 \r
+  assert (nn <= NPT);\r
+\r
   Number = (UINT16) GetBits (Sd, nbit);\r
 \r
   if (Number == 0) {\r
@@ -391,7 +397,7 @@ Returns:
 \r
   Index = 0;\r
 \r
-  while (Index < Number) {\r
+  while (Index < Number && Index < NPT) {\r
 \r
     CharC = (UINT16) (Sd->mBitBuf >> (BITBUFSIZ - 3));\r
 \r
@@ -410,14 +416,14 @@ Returns:
     if (Index == Special) {\r
       CharC = (UINT16) GetBits (Sd, 2);\r
       CharC--;\r
-      while ((INT16) (CharC) >= 0) {\r
+      while ((INT16) (CharC) >= 0 && Index < NPT) {\r
         Sd->mPTLen[Index++] = 0;\r
         CharC--;\r
       }\r
     }\r
   }\r
 \r
-  while (Index < nn) {\r
+  while (Index < nn && Index < NPT) {\r
     Sd->mPTLen[Index++] = 0;\r
   }\r
 \r
@@ -640,13 +646,23 @@ Returns: (VOID)
 \r
       BytesRemain--;\r
       while ((INT16) (BytesRemain) >= 0) {\r
-        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
         if (Sd->mOutBuf >= Sd->mOrigSize) {\r
           return ;\r
         }\r
+        if (DataIdx >= Sd->mOrigSize) {\r
+          Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r
+          return ;\r
+        }\r
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
 \r
         BytesRemain--;\r
       }\r
+      //\r
+      // Once mOutBuf is fully filled, directly return\r
+      //\r
+      if (Sd->mOutBuf >= Sd->mOrigSize) {\r
+        return ;\r
+      }\r
     }\r
   }\r
 \r
@@ -675,12 +691,13 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
 {\r
   UINT8 *Src;\r
+  UINT32 CompSize;\r
 \r
   *ScratchSize  = sizeof (SCRATCH_DATA);\r
 \r
@@ -689,7 +706,13 @@ Returns:
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
   *DstSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+\r
+  if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -719,7 +742,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_SUCCESS           - Decompression is successful\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -749,7 +772,7 @@ Returns:
   CompSize  = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);\r
   OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
 \r
-  if (SrcSize < CompSize + 8) {\r
+  if (SrcSize < CompSize + 8 || (CompSize + 8) < 8) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -810,7 +833,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -840,7 +863,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successull retrieved.\r
+  EFI_SUCCESS           - The size of destination buffer and the size of scratch buffer are successfully retrieved.\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -874,7 +897,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_SUCCESS           - Decompression is successful\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -909,7 +932,7 @@ Arguments:
 \r
 Returns:\r
 \r
-  EFI_SUCCESS           - Decompression is successfull\r
+  EFI_SUCCESS           - Decompression is successful\r
   EFI_INVALID_PARAMETER - The source data is corrupted\r
 \r
 --*/\r
@@ -931,7 +954,9 @@ Extract (
   UINT32        ScratchSize;\r
   EFI_STATUS    Status;\r
 \r
-  Status = EFI_SUCCESS;\r
+  Scratch = NULL;\r
+  Status  = EFI_SUCCESS;\r
+\r
   switch (Algorithm) {\r
   case 0:\r
     *Destination = (VOID *)malloc(SrcSize);\r
@@ -945,30 +970,44 @@ Extract (
     Status = EfiGetInfo(Source, SrcSize, DstSize, &ScratchSize);\r
     if (Status == EFI_SUCCESS) {\r
       Scratch = (VOID *)malloc(ScratchSize);\r
+      if (Scratch == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
       *Destination = (VOID *)malloc(*DstSize);\r
-      if (Scratch != NULL && *Destination != NULL) {\r
-        Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
-      } else {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      if (*Destination == NULL) {\r
+        free (Scratch);\r
+        return EFI_OUT_OF_RESOURCES;\r
       }\r
+\r
+      Status = EfiDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
     }\r
     break;\r
   case 2:\r
     Status = TianoGetInfo(Source, SrcSize, DstSize, &ScratchSize);\r
     if (Status == EFI_SUCCESS) {\r
       Scratch = (VOID *)malloc(ScratchSize);\r
+      if (Scratch == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
       *Destination = (VOID *)malloc(*DstSize);\r
-      if (Scratch != NULL && *Destination != NULL) {\r
-        Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
-      } else {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
+      if (*Destination == NULL) {\r
+        free (Scratch);\r
+        return EFI_OUT_OF_RESOURCES;\r
       }\r
+\r
+      Status = TianoDecompress(Source, SrcSize, *Destination, *DstSize, Scratch, ScratchSize);\r
     }\r
     break;\r
   default:\r
     Status = EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (Scratch != NULL) {\r
+    free (Scratch);\r
+  }\r
+\r
   return Status;\r
 }\r
 \r