X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FC%2FTianoCompress%2FTianoCompress.c;h=56a9f14c8791142ef45a9d69cc669952f06765dd;hb=2e351cbe8e190271b3716284fc1076551d005472;hp=145288bb8038a508956d44169fa92cd4146aaa41;hpb=b36d134faf4305247830522b8e2bb255e98c5699;p=mirror_edk2.git
diff --git a/BaseTools/Source/C/TianoCompress/TianoCompress.c b/BaseTools/Source/C/TianoCompress/TianoCompress.c
index 145288bb80..56a9f14c87 100644
--- a/BaseTools/Source/C/TianoCompress/TianoCompress.c
+++ b/BaseTools/Source/C/TianoCompress/TianoCompress.c
@@ -1,29 +1,17 @@
/** @file
+Compression routine. The compression algorithm is a mixture of LZ77 and Huffman
+coding. LZ77 transforms the source data into a sequence of Original Characters
+and Pointers to repeated strings.
+This sequence is further divided into Blocks and Huffman codings are applied to
+each Block.
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- TianoCompress.c
-
-Abstract:
-
- Compression routine. The compression algorithm is a mixture of
- LZ77 and Huffman coding. LZ77 transforms the source data into a
- sequence of Original Characters and Pointers to repeated strings.
- This sequence is further divided into Blocks and Huffman codings
- are applied to each Block.
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Compress.h"
+#include "Decompress.h"
#include "TianoCompress.h"
#include "EfiUtilityMsgs.h"
#include "ParseInf.h"
@@ -72,6 +60,7 @@ static BOOLEAN QuietMode = FALSE;
//
STATIC BOOLEAN ENCODE = FALSE;
STATIC BOOLEAN DECODE = FALSE;
+STATIC BOOLEAN UEFIMODE = FALSE;
STATIC UINT8 *mSrc, *mDst, *mSrcUpperLimit, *mDstUpperLimit;
STATIC UINT8 *mLevel, *mText, *mChildCount, *mBuf, mCLen[NC], mPTLen[NPT], *mLen;
STATIC INT16 mHeap[NC + 1];
@@ -107,7 +96,7 @@ Arguments:
SrcBuffer - The buffer storing the source data
SrcSize - The size of source data
DstBuffer - The buffer to store the compressed data
-
+
Version - The version of de/compression algorithm.
Version 1 for EFI 1.1 de/compression algorithm.
Version 2 for Tiano de/compression algorithm.
@@ -142,12 +131,12 @@ Returns:
mSrcUpperLimit = mSrc + SrcSize;
mDst = DstBuffer;
mDstUpperLimit = mDst +*DstSize;
-
+
PutDword (0L);
PutDword (0L);
-
+
MakeCrcTable ();
-
+
mOrigSize = mCompSize = 0;
mCrc = INIT_CRC;
@@ -158,7 +147,7 @@ Returns:
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
-
+
//
// Null terminate the compressed data
//
@@ -170,8 +159,8 @@ Returns:
//
// Fill in compressed size and original size
//
- mDst = DstBuffer;
-
+ mDst = DstBuffer;
+
PutDword (mCompSize + 1);
PutDword (mOrigSize);
//
@@ -179,10 +168,10 @@ Returns:
//
if (mCompSize + 1 + 8 > *DstSize) {
- *DstSize = mCompSize + 1 + 8;
+ *DstSize = mCompSize + 1 + 8;
return EFI_BUFFER_TOO_SMALL;
} else {
- *DstSize = mCompSize + 1 + 8;
+ *DstSize = mCompSize + 1 + 8;
return EFI_SUCCESS;
}
}
@@ -197,13 +186,13 @@ PutDword (
Routine Description:
Put a dword to output stream
-
+
Arguments:
Data - the dword to put
-
+
Returns: (VOID)
-
+
--*/
{
if (mDst < mDstUpperLimit) {
@@ -233,8 +222,8 @@ AllocateMemory (
Routine Description:
Allocate memory spaces for data structures used in compression process
-
-Argements:
+
+Arguments:
VOID
Returns:
@@ -247,6 +236,10 @@ Returns:
UINT32 Index;
mText = malloc (WNDSIZ * 2 + MAXMATCH);
+ if (mText == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
for (Index = 0; Index < WNDSIZ * 2 + MAXMATCH; Index++) {
mText[Index] = 0;
}
@@ -257,6 +250,11 @@ Returns:
mParent = malloc (WNDSIZ * 2 * sizeof (*mParent));
mPrev = malloc (WNDSIZ * 2 * sizeof (*mPrev));
mNext = malloc ((MAX_HASH_VAL + 1) * sizeof (*mNext));
+ if (mLevel == NULL || mChildCount == NULL || mPosition == NULL ||
+ mParent == NULL || mPrev == NULL || mNext == NULL) {
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
+ return EFI_OUT_OF_RESOURCES;
+ }
mBufSiz = BLKSIZ;
mBuf = malloc (mBufSiz);
@@ -283,7 +281,7 @@ FreeMemory (
Routine Description:
Called when compression is completed to free memory previously allocated.
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -335,7 +333,7 @@ InitSlide (
Routine Description:
Initialize String Info Log data structures
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -375,16 +373,16 @@ Child (
Routine Description:
Find child node given the parent node and the edge character
-
+
Arguments:
NodeQ - the parent node
CharC - the edge character
-
+
Returns:
- The child node (NIL if not found)
-
+ The child node (NIL if not found)
+
--*/
{
NODE NodeR;
@@ -413,13 +411,13 @@ MakeChild (
Routine Description:
Create a new child for a given parent node.
-
+
Arguments:
Parent - the parent node
CharC - the edge character
Child - the child node
-
+
Returns: (VOID)
--*/
@@ -447,11 +445,11 @@ Split (
Routine Description:
Split a node.
-
+
Arguments:
Old - the node to split
-
+
Returns: (VOID)
--*/
@@ -485,7 +483,7 @@ InsertNode (
Routine Description:
Insert string info for current position into the String Info Log
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -503,7 +501,7 @@ Returns: (VOID)
if (mMatchLen >= 4) {
//
// We have just got a long match, the target tree
- // can be located by MatchPos + 1. Travese the tree
+ // can be located by MatchPos + 1. Traverse the tree
// from bottom up to get to a proper starting point.
// The usage of PERC_FLAG ensures proper node deletion
// in DeleteNode() later.
@@ -618,7 +616,7 @@ Routine Description:
Delete outdated string info. (The Usage of PERC_FLAG
ensures a clean deletion)
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -749,7 +747,7 @@ Routine Description:
Arguments: (VOID)
Returns:
-
+
EFI_SUCCESS - The compression is successful
EFI_OUT_0F_RESOURCES - Not enough memory for compression process
@@ -835,7 +833,7 @@ CountTFreq (
Routine Description:
Count the frequencies for the Extra Set
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -894,13 +892,13 @@ WritePTLen (
Routine Description:
Outputs the code length array for the Extra Set or the Position Set.
-
+
Arguments:
Number - the number of symbols
nbit - the number of bits needed to represent 'n'
Special - the special symbol that needs to be take care of
-
+
Returns: (VOID)
--*/
@@ -942,7 +940,7 @@ WriteCLen (
Routine Description:
Outputs the code length array for Char&Length Set
-
+
Arguments: (VOID)
Returns: (VOID)
@@ -1032,11 +1030,11 @@ SendBlock (
Routine Description:
Huffman code the block and output it.
-
-Arguments:
+
+Arguments:
(VOID)
-Returns:
+Returns:
(VOID)
--*/
@@ -1244,7 +1242,7 @@ Routine Description:
Arguments:
Number - the rightmost n bits of the data is used
- x - the data
+ x - the data
Returns: (VOID)
@@ -1281,7 +1279,7 @@ FreadCrc (
Routine Description:
Read in source data
-
+
Arguments:
Pointer - the buffer to hold the data
@@ -1290,7 +1288,7 @@ Arguments:
Returns:
number of bytes actually read
-
+
--*/
{
INT32 Index;
@@ -1333,11 +1331,11 @@ CountLen (
Routine Description:
Count the number of each code length for a Huffman tree.
-
+
Arguments:
Index - the top node
-
+
Returns: (VOID)
--*/
@@ -1364,11 +1362,11 @@ MakeLen (
Routine Description:
Create code length array for a Huffman tree
-
+
Arguments:
Root - the root of the tree
-
+
Returns:
VOID
@@ -1460,7 +1458,7 @@ MakeCode (
Routine Description:
Assign code to each symbol based on the code length array
-
+
Arguments:
Number - number of symbols
@@ -1497,18 +1495,18 @@ MakeTree (
Routine Description:
Generates Huffman codes given a frequency distribution of symbols
-
+
Arguments:
NParm - number of symbols
FreqParm - frequency of each symbol
LenParm - code length for each symbol
CodeParm - code for each symbol
-
+
Returns:
Root of the Huffman tree.
-
+
--*/
{
INT32 Index;
@@ -1584,22 +1582,22 @@ GetFileContents (
OUT UINT32 *BufferLength
)
/*++
-
+
Routine Description:
-
+
Get the contents of file specified in InputFileName
into FileBuffer.
-
+
Arguments:
-
+
InputFileName - Name of the input file.
-
+
FileBuffer - Output buffer to contain data
- BufferLength - Actual length of the data
+ BufferLength - Actual length of the data
Returns:
-
+
EFI_SUCCESS on successful return
EFI_ABORTED if unable to open input file.
@@ -1613,18 +1611,18 @@ Returns:
//
// Copy the file contents to the output buffer.
//
- InputFile = fopen (InputFileName, "rb");
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
if (InputFile == NULL) {
Error (NULL, 0, 0001, "Error opening file: %s", InputFileName);
return EFI_ABORTED;
}
-
+
fseek (InputFile, 0, SEEK_END);
FileSize = ftell (InputFile);
fseek (InputFile, 0, SEEK_SET);
//
// Now read the contents of the file into the buffer
- //
+ //
if (FileSize > 0 && FileBuffer != NULL) {
if (fread (FileBuffer, FileSize, 1, InputFile) != 1) {
Error (NULL, 0, 0004, "Error reading contents of input file: %s", InputFileName);
@@ -1636,7 +1634,7 @@ Returns:
fclose (InputFile);
Size += (UINTN) FileSize;
*BufferLength = Size;
-
+
if (FileBuffer != NULL) {
return EFI_SUCCESS;
} else {
@@ -1691,18 +1689,20 @@ Returns:
// Summary usage
//
fprintf (stdout, "Usage: %s -e|-d [options] \n\n", UTILITY_NAME);
-
+
//
// Copyright declaration
- //
- fprintf (stdout, "Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.\n\n");
+ //
+ fprintf (stdout, "Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.\n\n");
//
// Details Option
//
fprintf (stdout, "Options:\n");
+ fprintf (stdout, " --uefi\n\
+ Enable UefiCompress, use TianoCompress when without this option\n");
fprintf (stdout, " -o FileName, --output FileName\n\
- File will be created to store the ouput content.\n");
+ File will be created to store the output content.\n");
fprintf (stdout, " -v, --verbose\n\
Turn on verbose output with informational messages.\n");
fprintf (stdout, " -q, --quiet\n\
@@ -1737,7 +1737,7 @@ Returns:
EFI_ABORTED Could not generate the section
EFI_OUT_OF_RESOURCES No resource to complete the operation.
---*/
+--*/
{
FILE *OutputFile;
char *OutputFileName;
@@ -1751,17 +1751,21 @@ Returns:
SCRATCH_DATA *Scratch;
UINT8 *Src;
UINT32 OrigSize;
+ UINT32 CompSize;
SetUtilityName(UTILITY_NAME);
-
+
FileBuffer = NULL;
Src = NULL;
OutBuffer = NULL;
Scratch = NULL;
OrigSize = 0;
+ CompSize = 0;
InputLength = 0;
InputFileName = NULL;
OutputFileName = NULL;
+ InputFile = NULL;
+ OutputFile = NULL;
DstSize=0;
DebugLevel = 0;
DebugMode = FALSE;
@@ -1774,12 +1778,12 @@ Returns:
Usage();
return 0;
}
-
+
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
Usage();
return 0;
}
-
+
if ((strcmp(argv[1], "--version") == 0)) {
Version();
return 0;
@@ -1818,6 +1822,13 @@ Returns:
continue;
}
+ if (stricmp(argv[0], "--uefi") == 0) {
+ UEFIMODE = TRUE;
+ argc--;
+ argv++;
+ continue;
+ }
+
if (stricmp (argv[0], "--debug") == 0) {
argc-=2;
argv++;
@@ -1850,7 +1861,7 @@ Returns:
OutputFileName = argv[1];
argc -=2;
argv +=2;
- continue;
+ continue;
}
if (argv[0][0]!='-') {
@@ -1861,7 +1872,7 @@ Returns:
}
Error (NULL, 0, 1000, "Unknown option", argv[0]);
- goto ERROR;
+ goto ERROR;
}
if (InputFileName == NULL) {
@@ -1879,7 +1890,7 @@ Returns:
} else if (DebugMode) {
SetPrintLevel(DebugLevel);
}
-
+
if (VerboseMode) {
VerboseMsg("%s tool start.\n", UTILITY_NAME);
}
@@ -1888,13 +1899,13 @@ Returns:
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
goto ERROR;
}
-
- InputFile = fopen (InputFileName, "rb");
+
+ InputFile = fopen (LongFilePath (InputFileName), "rb");
if (InputFile == NULL) {
Error (NULL, 0, 0001, "Error opening input file", InputFileName);
goto ERROR;
}
-
+
Status = GetFileContents(
InputFileName,
FileBuffer,
@@ -1904,7 +1915,7 @@ Returns:
FileBuffer = (UINT8 *) malloc (InputLength);
if (FileBuffer == NULL) {
Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- return 1;
+ goto ERROR;
}
Status = GetFileContents (
@@ -1915,24 +1926,19 @@ Returns:
}
if (EFI_ERROR(Status)) {
- free(FileBuffer);
- return 1;
+ Error (NULL, 0, 0004, "Error getting contents of file: %s", InputFileName);
+ goto ERROR;
}
-
- if (OutputFileName != NULL) {
- OutputFile = fopen (OutputFileName, "wb");
- if (OutputFile == NULL) {
- Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);
- if (InputFile != NULL) {
- fclose (InputFile);
- }
- goto ERROR;
- }
- } else {
- OutputFileName = DEFAULT_OUTPUT_FILE;
- OutputFile = fopen (OutputFileName, "wb");
- }
-
+
+ if (OutputFileName == NULL) {
+ OutputFileName = DEFAULT_OUTPUT_FILE;
+ }
+ OutputFile = fopen (LongFilePath (OutputFileName), "wb");
+ if (OutputFile == NULL) {
+ Error (NULL, 0, 0001, "Error opening output file for writing", OutputFileName);
+ goto ERROR;
+ }
+
if (ENCODE) {
//
// First call TianoCompress to get DstSize
@@ -1940,8 +1946,12 @@ Returns:
if (DebugMode) {
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding", NULL);
}
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
-
+ if (UEFIMODE) {
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ } else {
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ }
+
if (Status == EFI_BUFFER_TOO_SMALL) {
OutBuffer = (UINT8 *) malloc (DstSize);
if (OutBuffer == NULL) {
@@ -1949,13 +1959,25 @@ Returns:
goto ERROR;
}
}
- Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+
+ if (UEFIMODE) {
+ Status = EfiCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ } else {
+ Status = TianoCompress ((UINT8 *)FileBuffer, InputLength, OutBuffer, &DstSize);
+ }
if (Status != EFI_SUCCESS) {
Error (NULL, 0, 0007, "Error compressing file", NULL);
goto ERROR;
}
+ if (OutBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
fwrite(OutBuffer,(size_t)DstSize, 1, OutputFile);
+ fclose(OutputFile);
+ fclose(InputFile);
free(Scratch);
free(FileBuffer);
free(OutBuffer);
@@ -1966,47 +1988,72 @@ Returns:
if (VerboseMode) {
VerboseMsg("Encoding successful\n");
}
- return 0;
+ return 0;
}
else if (DECODE) {
if (DebugMode) {
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding\n", NULL);
}
- //
- // Get Compressed file original size
- //
- Src = (UINT8 *)FileBuffer;
- OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
-
- //
- // Allocate OutputBuffer
- //
- OutBuffer = (UINT8 *)malloc(OrigSize);
- if (OutBuffer == NULL) {
- Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
- goto ERROR;
- }
- Status = Decompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);
- if (Status != EFI_SUCCESS) {
- goto ERROR;
- }
+ if (UEFIMODE) {
+ Status = Extract((VOID *)FileBuffer, InputLength, (VOID *)&OutBuffer, &DstSize, 1);
+ if (Status != EFI_SUCCESS) {
+ goto ERROR;
+ }
+ fwrite(OutBuffer, (size_t)(DstSize), 1, OutputFile);
+ } else {
+ if (InputLength < 8){
+ Error (NULL, 0, 3000, "Invalid", "The input file %s is too small.", InputFileName);
+ goto ERROR;
+ }
+ //
+ // Get Compressed file original size
+ //
+ Src = (UINT8 *)FileBuffer;
+ OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
+ CompSize = Src[0] + (Src[1] << 8) + (Src[2] <<16) + (Src[3] <<24);
- fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);
- free(Scratch);
- free(FileBuffer);
- free(OutBuffer);
+ //
+ // Allocate OutputBuffer
+ //
+ if (InputLength < CompSize + 8 || (CompSize + 8) < 8) {
+ Error (NULL, 0, 3000, "Invalid", "The input file %s data is invalid.", InputFileName);
+ goto ERROR;
+ }
+ OutBuffer = (UINT8 *)malloc(OrigSize);
+ if (OutBuffer == NULL) {
+ Error (NULL, 0, 4001, "Resource:", "Memory cannot be allocated!");
+ goto ERROR;
+ }
+
+ Status = TDecompress((VOID *)FileBuffer, (VOID *)OutBuffer, (VOID *)Scratch, 2);
+ if (Status != EFI_SUCCESS) {
+ goto ERROR;
+ }
+ fwrite(OutBuffer, (size_t)(Scratch->mOrigSize), 1, OutputFile);
+ }
+ fclose(OutputFile);
+ fclose(InputFile);
+ if (Scratch != NULL) {
+ free(Scratch);
+ }
+ if (FileBuffer != NULL) {
+ free(FileBuffer);
+ }
+ if (OutBuffer != NULL) {
+ free(OutBuffer);
+ }
if (DebugMode) {
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Encoding successful!\n", NULL);
}
-
+
if (VerboseMode) {
VerboseMsg("Decoding successful\n");
}
return 0;
}
-
+
ERROR:
if (DebugMode) {
if (ENCODE) {
@@ -2015,6 +2062,12 @@ ERROR:
DebugMsg(UTILITY_NAME, 0, DebugLevel, "Decoding Error\n", NULL);
}
}
+ if (OutputFile != NULL) {
+ fclose(OutputFile);
+ }
+ if (InputFile != NULL) {
+ fclose (InputFile);
+ }
if (Scratch != NULL) {
free(Scratch);
}
@@ -2024,7 +2077,7 @@ ERROR:
if (OutBuffer != NULL) {
free(OutBuffer);
}
-
+
if (VerboseMode) {
VerboseMsg("%s tool done with return code is 0x%x.\n", UTILITY_NAME, GetUtilityStatus ());
}
@@ -2051,11 +2104,11 @@ Returns: (VOID)
--*/
{
- Sd->mBitBuf = (UINT32) (Sd->mBitBuf << NumOfBits);
+ Sd->mBitBuf = (UINT32) (((UINT64)Sd->mBitBuf) << NumOfBits);
while (NumOfBits > Sd->mBitCount) {
- Sd->mBitBuf |= (UINT32) (Sd->mSubBitBuf << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
+ Sd->mBitBuf |= (UINT32) (((UINT64)Sd->mSubBitBuf) << (NumOfBits = (UINT16) (NumOfBits - Sd->mBitCount)));
if (Sd->mCompSize > 0) {
//
@@ -2089,8 +2142,8 @@ GetBits (
Routine Description:
- Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
- NumOfBits of bits from source. Returns NumOfBits of bits that are
+ Get NumOfBits of bits out from mBitBuf. Fill mBitBuf with subsequent
+ NumOfBits of bits from source. Returns NumOfBits of bits that are
popped out.
Arguments:
@@ -2134,9 +2187,9 @@ Arguments:
BitLen - Code length array
TableBits - The width of the mapping table
Table - The table
-
+
Returns:
-
+
0 - OK.
BAD_TABLE - The table is corrupted.
@@ -2147,7 +2200,7 @@ Returns:
UINT16 Start[18];
UINT16 *Pointer;
UINT16 Index3;
- volatile UINT16 Index;
+ UINT16 Index;
UINT16 Len;
UINT16 Char;
UINT16 JuBits;
@@ -2156,15 +2209,20 @@ Returns:
UINT16 Mask;
UINT16 WordOfStart;
UINT16 WordOfCount;
+ UINT16 MaxTableLength;
- for (Index = 1; Index <= 16; Index++) {
+ for (Index = 0; Index <= 16; Index++) {
Count[Index] = 0;
}
for (Index = 0; Index < NumOfChar; Index++) {
+ if (BitLen[Index] > 16) {
+ return (UINT16) BAD_TABLE;
+ }
Count[BitLen[Index]]++;
}
+ Start[0] = 0;
Start[1] = 0;
for (Index = 1; Index <= 16; Index++) {
@@ -2182,6 +2240,7 @@ Returns:
JuBits = (UINT16) (16 - TableBits);
+ Weight[0] = 0;
for (Index = 1; Index <= TableBits; Index++) {
Start[Index] >>= JuBits;
Weight[Index] = (UINT16) (1U << (TableBits - Index));
@@ -2203,11 +2262,12 @@ Returns:
Avail = NumOfChar;
Mask = (UINT16) (1U << (15 - TableBits));
+ MaxTableLength = (UINT16) (1U << TableBits);
for (Char = 0; Char < NumOfChar; Char++) {
Len = BitLen[Char];
- if (Len == 0) {
+ if (Len == 0 || Len >= 17) {
continue;
}
@@ -2215,6 +2275,10 @@ Returns:
if (Len <= TableBits) {
+ if (Start[Len] >= NextCode || NextCode > MaxTableLength){
+ return (UINT16) BAD_TABLE;
+ }
+
for (Index = Start[Len]; Index < NextCode; Index++) {
Table[Index] = Char;
}
@@ -2324,7 +2388,7 @@ Arguments:
Sd - The global scratch data
nn - Number of symbols
nbit - Number of bits needed to represent nn
- Special - The special symbol that needs to be taken care of
+ Special - The special symbol that needs to be taken care of
Returns:
@@ -2338,6 +2402,8 @@ Returns:
volatile UINT16 Index;
UINT32 Mask;
+ assert (nn <= NPT);
+
Number = (UINT16) GetBits (Sd, nbit);
if (Number == 0) {
@@ -2598,14 +2664,25 @@ Returns: (VOID)
DataIdx = Sd->mOutBuf - DecodeP (Sd) - 1;
BytesRemain--;
+
while ((INT16) (BytesRemain) >= 0) {
- Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
if (Sd->mOutBuf >= Sd->mOrigSize) {
goto Done ;
}
+ if (DataIdx >= Sd->mOrigSize) {
+ Sd->mBadTableFlag = (UINT16) BAD_TABLE;
+ goto Done ;
+ }
+ Sd->mDstBase[Sd->mOutBuf++] = Sd->mDstBase[DataIdx++];
BytesRemain--;
}
+ //
+ // Once mOutBuf is fully filled, directly return
+ //
+ if (Sd->mOutBuf >= Sd->mOrigSize) {
+ goto Done ;
+ }
}
}
@@ -2615,7 +2692,7 @@ Done:
RETURN_STATUS
EFIAPI
-Decompress (
+TDecompress (
IN VOID *Source,
IN OUT VOID *Destination,
IN OUT VOID *Scratch,
@@ -2632,11 +2709,11 @@ Arguments:
Source - The source buffer containing the compressed data.
Destination - The destination buffer to store the decompressed data
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
- Version - 1 for EFI1.1 Decompress algoruthm, 2 for Tiano Decompress algorithm
+ Version - 1 for EFI1.1 Decompress algorithm, 2 for Tiano Decompress algorithm
Returns:
- RETURN_SUCCESS - Decompression is successfull
+ RETURN_SUCCESS - Decompression is successful
RETURN_INVALID_PARAMETER - The source data is corrupted
--*/
@@ -2654,14 +2731,14 @@ Returns:
assert(Source);
// assert(Destination);
assert(Scratch);
-
+
Src = (UINT8 *)Source;
Dst = (UINT8 *)Destination;
Sd = (SCRATCH_DATA *) Scratch;
CompSize = Src[0] + (Src[1] << 8) + (Src[2] << 16) + (Src[3] << 24);
OrigSize = Src[4] + (Src[5] << 8) + (Src[6] << 16) + (Src[7] << 24);
-
+
//
// If compressed file size is 0, return
//
@@ -2702,9 +2779,9 @@ Returns:
//
// Decompress it
//
-
+
Decode (Sd);
-
+
if (Sd->mBadTableFlag != 0) {
//
// Something wrong with the source