diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/SBaseCommon.cpp | 24 | ||||
| -rw-r--r-- | src/SFileReadFile.cpp | 10 | ||||
| -rw-r--r-- | src/StormCommon.h | 14 | 
3 files changed, 29 insertions, 19 deletions
diff --git a/src/SBaseCommon.cpp b/src/SBaseCommon.cpp index 23c9833..9509b6f 100644 --- a/src/SBaseCommon.cpp +++ b/src/SBaseCommon.cpp @@ -988,8 +988,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)          {              ULONGLONG RawFilePos = hf->RawFilePos; +            // Append the length of the patch info, if any              if(hf->pPatchInfo != NULL) +            { +                if((RawFilePos + hf->pPatchInfo->dwLength) < RawFilePos) +                    return ERROR_FILE_CORRUPT;                  RawFilePos += hf->pPatchInfo->dwLength; +            }              // Load the sector offsets from the file              if(!FileStream_Read(ha->pStream, &RawFilePos, hf->SectorOffsets, dwSectorOffsLen)) @@ -1043,12 +1048,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)                  // The sector size must not be bigger than compressed file size                  // Edit: Yes, but apparently, in original Storm.dll, the compressed -                // size is not checked anywhere -//              if((dwSectorOffset1 - dwSectorOffset0) > pFileEntry->dwCmpSize) -//              { -//                  bSectorOffsetTableCorrupt = true; -//                  break; -//              } +                // size is not checked anywhere. However, we need to do this check +                // in order to sector offset table malformed by MPQ protectors +                if((dwSectorOffset1 - dwSectorOffset0) > ha->dwSectorSize) +                { +                    bSectorOffsetTableCorrupt = true; +                    break; +                }              }              // If data corruption detected, free the sector offset table @@ -1070,9 +1076,13 @@ int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile)              if(hf->SectorOffsets[0] > dwSectorOffsLen)              { +                // MPQ protectors put some ridiculous values there. We must limit the extra bytes +                if(hf->SectorOffsets[0] > (dwSectorOffsLen + 0x400)) +                    return ERROR_FILE_CORRUPT; + +                // Free the old sector offset table                  dwSectorOffsLen = hf->SectorOffsets[0];                  STORM_FREE(hf->SectorOffsets); -                hf->SectorOffsets = NULL;                  goto __LoadSectorOffsets;              }          } diff --git a/src/SFileReadFile.cpp b/src/SFileReadFile.cpp index 02def18..2451865 100644 --- a/src/SFileReadFile.cpp +++ b/src/SFileReadFile.cpp @@ -81,14 +81,14 @@ static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DW  //              return nError;  //      } -        // If the file is compressed, also allocate secondary buffer -        pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwBytesToRead); -        if(pbRawSector == NULL) -            return ERROR_NOT_ENOUGH_MEMORY; -          // Assign the temporary buffer as target for read operation          dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex];          dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; + +        // If the file is compressed, also allocate secondary buffer +        pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead); +        if(pbRawSector == NULL) +            return ERROR_NOT_ENOUGH_MEMORY;      }      // Calculate raw file offset where the sector(s) are stored. diff --git a/src/StormCommon.h b/src/StormCommon.h index 93193cf..00ea3d8 100644 --- a/src/StormCommon.h +++ b/src/StormCommon.h @@ -105,17 +105,17 @@ typedef struct _MPQ_SIGNATURE_INFO  //  - Memory freeing function doesn't have to test the pointer to NULL  // -//#if defined(_MSC_VER) && defined(_DEBUG) -// -//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) -//#define STORM_FREE(ptr)           HeapFree(GetProcessHeap(), 0, ptr) -// -//#else +#if defined(_MSC_VER) && defined(_DEBUG) + +#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type))) +#define STORM_FREE(ptr)           HeapFree(GetProcessHeap(), 0, ptr) + +#else  #define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type))  #define STORM_FREE(ptr)           free(ptr) -//#endif +#endif  //-----------------------------------------------------------------------------  // StormLib internal global variables  | 
