]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/TianoCompress/TianoCompress.c
BaseTools: Add more checker in Decompress algorithm to access the valid buffer (CVE...
[mirror_edk2.git] / BaseTools / Source / C / TianoCompress / TianoCompress.c
index 44dbccf9ad2bd046f9e50b4cf946b9dedc3b08b6..2d6fc4c952cfa5e4bbe2513c286de781676b2bfb 100644 (file)
@@ -1,22 +1,23 @@
 /** @file\r
-Compression routine. The compression algorithm is a mixture of LZ77 and Huffman \r
-coding. LZ77 transforms the source data into a sequence of Original Characters \r
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman\r
+coding. LZ77 transforms the source data into a sequence of Original Characters\r
 and Pointers to repeated strings.\r
-This sequence is further divided into Blocks and Huffman codings are applied to \r
+This sequence is further divided into Blocks and Huffman codings are applied to\r
 each Block.\r
-  \r
-Copyright (c) 2007 - 2016, 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
+\r
+Copyright (c) 2007 - 2018, 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
 \r
 **/\r
 \r
 #include "Compress.h"\r
+#include "Decompress.h"\r
 #include "TianoCompress.h"\r
 #include "EfiUtilityMsgs.h"\r
 #include "ParseInf.h"\r
@@ -65,6 +66,7 @@ static BOOLEAN QuietMode = FALSE;
 //\r
 STATIC BOOLEAN ENCODE = FALSE;\r
 STATIC BOOLEAN DECODE = FALSE;\r
+STATIC BOOLEAN UEFIMODE = FALSE;\r
 STATIC UINT8  *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;\r
 STATIC UINT8  *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;\r
 STATIC INT16  mHeap[NC + 1];\r
@@ -100,7 +102,7 @@ Arguments:
   SrcBuffer   - The buffer storing the source data\r
   SrcSize     - The size of source data\r
   DstBuffer   - The buffer to store the compressed data\r
-  \r
+\r
   Version     - The version of de/compression algorithm.\r
                 Version 1 for EFI 1.1 de/compression algorithm.\r
                 Version 2 for Tiano de/compression algorithm.\r
@@ -135,12 +137,12 @@ Returns:
   mSrcUpperLimit  = mSrc + SrcSize;\r
   mDst            = DstBuffer;\r
   mDstUpperLimit  = mDst +*DstSize;\r
-    \r
+\r
   PutDword (0L);\r
   PutDword (0L);\r
-  \r
+\r
   MakeCrcTable ();\r
-  \r
+\r
   mOrigSize             = mCompSize = 0;\r
   mCrc                  = INIT_CRC;\r
 \r
@@ -151,7 +153,7 @@ Returns:
   if (EFI_ERROR (Status)) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // Null terminate the compressed data\r
   //\r
@@ -163,8 +165,8 @@ Returns:
   //\r
   // Fill in compressed size and original size\r
   //\r
-  mDst = DstBuffer; \r
\r
+  mDst = DstBuffer;\r
+\r
   PutDword (mCompSize + 1);\r
   PutDword (mOrigSize);\r
   //\r
@@ -172,10 +174,10 @@ Returns:
   //\r
 \r
   if (mCompSize + 1 + 8 > *DstSize) {\r
-    *DstSize = mCompSize + 1 + 8;    \r
+    *DstSize = mCompSize + 1 + 8;\r
     return EFI_BUFFER_TOO_SMALL;\r
   } else {\r
-    *DstSize = mCompSize + 1 + 8;   \r
+    *DstSize = mCompSize + 1 + 8;\r
     return EFI_SUCCESS;\r
   }\r
 }\r
@@ -190,13 +192,13 @@ PutDword (
 Routine Description:\r
 \r
   Put a dword to output stream\r
-  \r
+\r
 Arguments:\r
 \r
   Data    - the dword to put\r
-  \r
+\r
 Returns: (VOID)\r
-  \r
+\r
 --*/\r
 {\r
   if (mDst < mDstUpperLimit) {\r
@@ -226,8 +228,8 @@ AllocateMemory (
 Routine Description:\r
 \r
   Allocate memory spaces for data structures used in compression process\r
-  \r
-Argements: \r
+\r
+Argements:\r
   VOID\r
 \r
 Returns:\r
@@ -285,7 +287,7 @@ FreeMemory (
 Routine Description:\r
 \r
   Called when compression is completed to free memory previously allocated.\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -337,7 +339,7 @@ InitSlide (
 Routine Description:\r
 \r
   Initialize String Info Log data structures\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -377,16 +379,16 @@ Child (
 Routine Description:\r
 \r
   Find child node given the parent node and the edge character\r
-  \r
+\r
 Arguments:\r
 \r
   NodeQ       - the parent node\r
   CharC       - the edge character\r
-  \r
+\r
 Returns:\r
 \r
-  The child node (NIL if not found)  \r
-  \r
+  The child node (NIL if not found)\r
+\r
 --*/\r
 {\r
   NODE  NodeR;\r
@@ -415,13 +417,13 @@ MakeChild (
 Routine Description:\r
 \r
   Create a new child for a given parent node.\r
-  \r
+\r
 Arguments:\r
 \r
   Parent       - the parent node\r
   CharC   - the edge character\r
   Child       - the child node\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -449,11 +451,11 @@ Split (
 Routine Description:\r
 \r
   Split a node.\r
-  \r
+\r
 Arguments:\r
 \r
   Old     - the node to split\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -487,7 +489,7 @@ InsertNode (
 Routine Description:\r
 \r
   Insert string info for current position into the String Info Log\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -620,7 +622,7 @@ Routine Description:
 \r
   Delete outdated string info. (The Usage of PERC_FLAG\r
   ensures a clean deletion)\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -751,7 +753,7 @@ Routine Description:
 Arguments: (VOID)\r
 \r
 Returns:\r
-  \r
+\r
   EFI_SUCCESS           - The compression is successful\r
   EFI_OUT_0F_RESOURCES  - Not enough memory for compression process\r
 \r
@@ -837,7 +839,7 @@ CountTFreq (
 Routine Description:\r
 \r
   Count the frequencies for the Extra Set\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -896,13 +898,13 @@ WritePTLen (
 Routine Description:\r
 \r
   Outputs the code length array for the Extra Set or the Position Set.\r
-  \r
+\r
 Arguments:\r
 \r
   Number       - the number of symbols\r
   nbit    - the number of bits needed to represent 'n'\r
   Special - the special symbol that needs to be take care of\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -944,7 +946,7 @@ WriteCLen (
 Routine Description:\r
 \r
   Outputs the code length array for Char&Length Set\r
-  \r
+\r
 Arguments: (VOID)\r
 \r
 Returns: (VOID)\r
@@ -1034,11 +1036,11 @@ SendBlock (
 Routine Description:\r
 \r
   Huffman code the block and output it.\r
-  \r
-Arguments: \r
+\r
+Arguments:\r
   (VOID)\r
 \r
-Returns: \r
+Returns:\r
   (VOID)\r
 \r
 --*/\r
@@ -1246,7 +1248,7 @@ Routine Description:
 Arguments:\r
 \r
   Number   - the rightmost n bits of the data is used\r
-  x   - the data \r
+  x   - the data\r
 \r
 Returns: (VOID)\r
 \r
@@ -1283,7 +1285,7 @@ FreadCrc (
 Routine Description:\r
 \r
   Read in source data\r
-  \r
+\r
 Arguments:\r
 \r
   Pointer   - the buffer to hold the data\r
@@ -1292,7 +1294,7 @@ Arguments:
 Returns:\r
 \r
   number of bytes actually read\r
-  \r
+\r
 --*/\r
 {\r
   INT32 Index;\r
@@ -1335,11 +1337,11 @@ CountLen (
 Routine Description:\r
 \r
   Count the number of each code length for a Huffman tree.\r
-  \r
+\r
 Arguments:\r
 \r
   Index   - the top node\r
-  \r
+\r
 Returns: (VOID)\r
 \r
 --*/\r
@@ -1366,11 +1368,11 @@ MakeLen (
 Routine Description:\r
 \r
   Create code length array for a Huffman tree\r
-  \r
+\r
 Arguments:\r
 \r
   Root   - the root of the tree\r
-  \r
+\r
 Returns:\r
 \r
   VOID\r
@@ -1462,7 +1464,7 @@ MakeCode (
 Routine Description:\r
 \r
   Assign code to each symbol based on the code length array\r
-  \r
+\r
 Arguments:\r
 \r
   Number     - number of symbols\r
@@ -1499,18 +1501,18 @@ MakeTree (
 Routine Description:\r
 \r
   Generates Huffman codes given a frequency distribution of symbols\r
-  \r
+\r
 Arguments:\r
 \r
   NParm    - number of symbols\r
   FreqParm - frequency of each symbol\r
   LenParm  - code length for each symbol\r
   CodeParm - code for each symbol\r
-  \r
+\r
 Returns:\r
 \r
   Root of the Huffman tree.\r
-  \r
+\r
 --*/\r
 {\r
   INT32 Index;\r
@@ -1586,22 +1588,22 @@ GetFileContents (
   OUT UINT32  *BufferLength\r
   )\r
 /*++\r
-        \r
+\r
 Routine Description:\r
-           \r
+\r
   Get the contents of file specified in InputFileName\r
   into FileBuffer.\r
-            \r
+\r
 Arguments:\r
-               \r
+\r
   InputFileName  - Name of the input file.\r
-                \r
+\r
   FileBuffer     - Output buffer to contain data\r
 \r
-  BufferLength   - Actual length of the data \r
+  BufferLength   - Actual length of the data\r
 \r
 Returns:\r
-                       \r
+\r
   EFI_SUCCESS on successful return\r
   EFI_ABORTED if unable to open input file.\r
 \r
@@ -1620,13 +1622,13 @@ Returns:
       Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);\r
       return EFI_ABORTED;\r
     }\r
-  \r
+\r
   fseek (InputFile, 0, SEEK_END);\r
   FileSize = ftell (InputFile);\r
   fseek (InputFile, 0, SEEK_SET);\r
     //\r
     // Now read the contents of the file into the buffer\r
-    // \r
+    //\r
     if (FileSize > 0 && FileBuffer != NULL) {\r
       if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {\r
         Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);\r
@@ -1638,7 +1640,7 @@ Returns:
   fclose (InputFile);\r
   Size += (UINTN) FileSize;\r
   *BufferLength = Size;\r
-  \r
+\r
   if (FileBuffer != NULL) {\r
     return EFI_SUCCESS;\r
   } else {\r
@@ -1693,16 +1695,18 @@ Returns:
   // Summary usage\r
   //\r
   fprintf (stdout, "Usage: %s -e|-d [options] <input_file>\n\n", UTILITY_NAME);\r
-  \r
+\r
   //\r
   // Copyright declaration\r
-  // \r
-  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
+  //\r
+  fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");\r
 \r
   //\r
   // Details Option\r
   //\r
   fprintf (stdout, "Options:\n");\r
+  fprintf (stdout, "  --uefi\n\\r
+            Enable UefiCompress, use TianoCompress when without this option\n");\r
   fprintf (stdout, "  -o FileName, --output FileName\n\\r
             File will be created to store the ouput content.\n");\r
   fprintf (stdout, "  -v, --verbose\n\\r
@@ -1739,7 +1743,7 @@ Returns:
   EFI_ABORTED    Could not generate the section\r
   EFI_OUT_OF_RESOURCES  No resource to complete the operation.\r
 \r
---*/  \r
+--*/\r
 {\r
   FILE       *OutputFile;\r
   char       *OutputFileName;\r
@@ -1753,17 +1757,21 @@ Returns:
   SCRATCH_DATA      *Scratch;\r
   UINT8      *Src;\r
   UINT32     OrigSize;\r
+  UINT32     CompSize;\r
 \r
   SetUtilityName(UTILITY_NAME);\r
-  \r
+\r
   FileBuffer = NULL;\r
   Src = NULL;\r
   OutBuffer = NULL;\r
   Scratch   = NULL;\r
   OrigSize = 0;\r
+  CompSize = 0;\r
   InputLength = 0;\r
   InputFileName = NULL;\r
   OutputFileName = NULL;\r
+  InputFile = NULL;\r
+  OutputFile = NULL;\r
   DstSize=0;\r
   DebugLevel = 0;\r
   DebugMode = FALSE;\r
@@ -1776,12 +1784,12 @@ Returns:
     Usage();\r
     return 0;\r
   }\r
-  \r
+\r
   if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {\r
     Usage();\r
     return 0;\r
   }\r
-  \r
+\r
   if ((strcmp(argv[1], "--version") == 0)) {\r
     Version();\r
     return 0;\r
@@ -1820,6 +1828,13 @@ Returns:
       continue;\r
     }\r
 \r
+    if (stricmp(argv[0], "--uefi") == 0) {\r
+      UEFIMODE = TRUE;\r
+      argc--;\r
+      argv++;\r
+      continue;\r
+    }\r
+\r
     if (stricmp (argv[0], "--debug") == 0) {\r
       argc-=2;\r
       argv++;\r
@@ -1852,7 +1867,7 @@ Returns:
       OutputFileName = argv[1];\r
       argc -=2;\r
       argv +=2;\r
-      continue; \r
+      continue;\r
     }\r
 \r
     if (argv[0][0]!='-') {\r
@@ -1863,7 +1878,7 @@ Returns:
     }\r
 \r
     Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
-    goto ERROR;     \r
+    goto ERROR;\r
   }\r
 \r
   if (InputFileName == NULL) {\r
@@ -1881,7 +1896,7 @@ Returns:
   } else if (DebugMode) {\r
     SetPrintLevel(DebugLevel);\r
   }\r
-  \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("%s tool start.\n", UTILITY_NAME);\r
    }\r
@@ -1890,13 +1905,13 @@ Returns:
     Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
     goto ERROR;\r
   }\r
-    \r
+\r
   InputFile = fopen (LongFilePath (InputFileName), "rb");\r
   if (InputFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening input file", InputFileName);\r
     goto ERROR;\r
   }\r
-        \r
+\r
   Status = GetFileContents(\r
             InputFileName,\r
             FileBuffer,\r
@@ -1927,12 +1942,9 @@ Returns:
   OutputFile = fopen (LongFilePath (OutputFileName), "wb");\r
   if (OutputFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);\r
-    if (InputFile != NULL) {\r
-      fclose (InputFile);\r
-    }\r
     goto ERROR;\r
   }\r
-    \r
+\r
   if (ENCODE) {\r
   //\r
   // First call TianoCompress to get DstSize\r
@@ -1940,8 +1952,12 @@ Returns:
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);\r
   }\r
-  Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
-  \r
+  if (UEFIMODE) {\r
+    Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  } else {\r
+    Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  }\r
+\r
   if (Status == EFI_BUFFER_TOO_SMALL) {\r
     OutBuffer = (UINT8 *) malloc (DstSize);\r
     if (OutBuffer == NULL) {\r
@@ -1950,7 +1966,11 @@ Returns:
     }\r
   }\r
 \r
-  Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  if (UEFIMODE) {\r
+    Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  } else {\r
+    Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);\r
+  }\r
   if (Status != EFI_SUCCESS) {\r
     Error (NULL, 0, 0007, "Error compressing file", NULL);\r
     goto ERROR;\r
@@ -1962,6 +1982,8 @@ Returns:
   }\r
 \r
   fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);\r
+  fclose(OutputFile);\r
+  fclose(InputFile);\r
   free(Scratch);\r
   free(FileBuffer);\r
   free(OutBuffer);\r
@@ -1972,47 +1994,72 @@ Returns:
   if (VerboseMode) {\r
     VerboseMsg("Encoding successful\n");\r
   }\r
-  return 0;  \r
+  return 0;\r
   }\r
   else if (DECODE) {\r
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);\r
   }\r
-  //\r
-  // Get Compressed file original size\r
-  // \r
-  Src     = (UINT8 *)FileBuffer;                     \r
-  OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);  \r
-  \r
-  //\r
-  // Allocate OutputBuffer\r
-  //\r
-  OutBuffer = (UINT8 *)malloc(OrigSize);\r
-  if (OutBuffer == NULL) {\r
-    Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
-    goto ERROR;\r
-   }  \r
 \r
-  Status = Decompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
-  if (Status != EFI_SUCCESS) {\r
-   goto ERROR;         \r
-  }\r
+  if (UEFIMODE) {\r
+    Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);\r
+    if (Status != EFI_SUCCESS) {\r
+      goto ERROR;\r
+    }\r
+    fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);\r
+  } else {\r
+    if (InputLength < 8){\r
+      Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);\r
+      goto ERROR;\r
+    }\r
+    //\r
+    // Get Compressed file original size\r
+    //\r
+    Src     = (UINT8 *)FileBuffer;\r
+    OrigSize  = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);\r
+    CompSize  = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);\r
 \r
-  fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
-  free(Scratch);\r
-  free(FileBuffer);\r
-  free(OutBuffer);\r
+    //\r
+    // Allocate OutputBuffer\r
+    //\r
+    if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {\r
+      Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);\r
+      goto ERROR;\r
+    }\r
+    OutBuffer = (UINT8 *)malloc(OrigSize);\r
+    if (OutBuffer == NULL) {\r
+      Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");\r
+      goto ERROR;\r
+     }\r
+\r
+    Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);\r
+    if (Status != EFI_SUCCESS) {\r
+      goto ERROR;\r
+    }\r
+    fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);\r
+  }\r
+  fclose(OutputFile);\r
+  fclose(InputFile);\r
+  if (Scratch != NULL) {\r
+    free(Scratch);\r
+  }\r
+  if (FileBuffer != NULL) {\r
+    free(FileBuffer);\r
+  }\r
+  if (OutBuffer != NULL) {\r
+    free(OutBuffer);\r
+  }\r
 \r
   if (DebugMode) {\r
     DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);\r
   }\r
-  \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("Decoding successful\n");\r
   }\r
   return 0;\r
   }\r
-  \r
+\r
 ERROR:\r
   if (DebugMode) {\r
     if (ENCODE) {\r
@@ -2021,6 +2068,12 @@ ERROR:
       DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);\r
     }\r
   }\r
+  if (OutputFile != NULL) {\r
+    fclose(OutputFile);\r
+  }\r
+  if (InputFile != NULL) {\r
+    fclose (InputFile);\r
+  }\r
   if (Scratch != NULL) {\r
     free(Scratch);\r
   }\r
@@ -2030,7 +2083,7 @@ ERROR:
   if (OutBuffer != NULL) {\r
     free(OutBuffer);\r
   }\r
-    \r
+\r
   if (VerboseMode) {\r
     VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());\r
   }\r
@@ -2057,11 +2110,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
@@ -2095,8 +2148,8 @@ GetBits (
 \r
 Routine Description:\r
 \r
-  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent \r
-  NumOfBits of bits from source. Returns NumOfBits of bits that are \r
+  Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent\r
+  NumOfBits of bits from source. Returns NumOfBits of bits that are\r
   popped out.\r
 \r
 Arguments:\r
@@ -2140,9 +2193,9 @@ Arguments:
   BitLen    - Code length array\r
   TableBits - The width of the mapping table\r
   Table     - The table\r
-  \r
+\r
 Returns:\r
-  \r
+\r
   0         - OK.\r
   BAD_TABLE - The table is corrupted.\r
 \r
@@ -2162,12 +2215,16 @@ Returns:
   UINT16  Mask;\r
   UINT16  WordOfStart;\r
   UINT16  WordOfCount;\r
+  UINT16  MaxTableLength;\r
 \r
   for (Index = 0; 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
@@ -2211,6 +2268,7 @@ 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
@@ -2224,6 +2282,9 @@ Returns:
     if (Len <= TableBits) {\r
 \r
       for (Index = Start[Len]; Index < NextCode; Index++) {\r
+        if (Index >= MaxTableLength) {\r
+          return (UINT16) BAD_TABLE;\r
+        }\r
         Table[Index] = Char;\r
       }\r
 \r
@@ -2332,7 +2393,7 @@ Arguments:
   Sd        - The global scratch data\r
   nn        - Number of symbols\r
   nbit      - Number of bits needed to represent nn\r
-  Special   - The special symbol that needs to be taken care of \r
+  Special   - The special symbol that needs to be taken care of\r
 \r
 Returns:\r
 \r
@@ -2608,11 +2669,16 @@ Returns: (VOID)
       DataIdx     = Sd->mOutBuf - DecodeP (Sd) - 1;\r
 \r
       BytesRemain--;\r
+\r
       while ((INT16) (BytesRemain) >= 0) {\r
-        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
         if (Sd->mOutBuf >= Sd->mOrigSize) {\r
           goto Done ;\r
         }\r
+        if (DataIdx >= Sd->mOrigSize) {\r
+          Sd->mBadTableFlag = (UINT16) BAD_TABLE;\r
+          goto Done ;\r
+        }\r
+        Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];\r
 \r
         BytesRemain--;\r
       }\r
@@ -2625,7 +2691,7 @@ Done:
 \r
 RETURN_STATUS\r
 EFIAPI\r
-Decompress (\r
+TDecompress (\r
   IN VOID  *Source,\r
   IN OUT VOID    *Destination,\r
   IN OUT VOID    *Scratch,\r
@@ -2664,14 +2730,14 @@ Returns:
   assert(Source);\r
 //  assert(Destination);\r
   assert(Scratch);\r
-  \r
+\r
   Src     = (UINT8 *)Source;\r
   Dst     = (UINT8 *)Destination;\r
 \r
   Sd      = (SCRATCH_DATA *) Scratch;\r
   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
+\r
   //\r
   // If compressed file size is 0, return\r
   //\r
@@ -2712,9 +2778,9 @@ Returns:
   //\r
   // Decompress it\r
   //\r
-  \r
+\r
   Decode (Sd);\r
-  \r
+\r
   if (Sd->mBadTableFlag != 0) {\r
     //\r
     // Something wrong with the source\r