diff --git a/Minecraft.Client/Common/DLC/DLCManager.cpp b/Minecraft.Client/Common/DLC/DLCManager.cpp index 2e307423..8231391a 100644 --- a/Minecraft.Client/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Common/DLC/DLCManager.cpp @@ -71,6 +71,11 @@ static bool hasPckFolderFallback(const wstring &path, wstring &folderPath) return true; } +static bool isValidDLCRange(const PBYTE pbData, DWORD dwLength, unsigned int offset, size_t size) +{ + return offset <= dwLength && size <= static_cast(dwLength) - offset; +} + static DLCManager::EDLCType getFolderFileType(const wstring &path) { wstring lowerPath = toLower(path); @@ -568,8 +573,14 @@ bool DLCManager::readDLCDataFolder(DWORD &dwFilesProcessed, const wstring &path, bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack) { + if(pbData == nullptr || pack == nullptr || dwLength < sizeof(unsigned int) * 2) + { + return false; + } + + const PBYTE pbEnd = pbData + dwLength; unordered_map parameterMapping; - unsigned int uiCurrentByte=0; + unsigned int uiCurrentByte = 0; // File format defined in the DLC_Creator // File format: Version 2 @@ -582,78 +593,146 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD // // unsigned long, p = number of parameters // // p * DLC_FILE_PARAM describing each parameter for this file // // ulFileSize bytes of data blob of the file added - unsigned int uiVersion=readUInt32(pbData, false); - uiCurrentByte+=sizeof(int); + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, sizeof(unsigned int))) + { + return false; + } + unsigned int uiVersion = readUInt32(pbData, false); + uiCurrentByte += sizeof(unsigned int); bool bSwapEndian = false; unsigned int uiVersionSwapped = SwapInt32(uiVersion); - if (uiVersion >= 0 && uiVersion <= CURRENT_DLC_VERSION_NUM) { - bSwapEndian = false; - } else if (uiVersionSwapped >= 0 && uiVersionSwapped <= CURRENT_DLC_VERSION_NUM) { - bSwapEndian = true; - } else { - if(pbData!=nullptr) delete [] pbData; - app.DebugPrintf("Unknown DLC version of %d\n", uiVersion); + if(uiVersion <= CURRENT_DLC_VERSION_NUM) + { + bSwapEndian = false; + } + else if(uiVersionSwapped <= CURRENT_DLC_VERSION_NUM) + { + bSwapEndian = true; + } + else + { + app.DebugPrintf("Unknown DLC version of %u\n", uiVersion); return false; } pack->SetDataPointer(pbData); - unsigned int uiParameterCount=readUInt32(&pbData[uiCurrentByte], bSwapEndian); - uiCurrentByte+=sizeof(int); - C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; - bool bXMLVersion = false; - //DWORD dwwchCount=0; - for(unsigned int i=0;idwType = bSwapEndian ? SwapInt32(pParams->dwType) : pParams->dwType; - pParams->dwWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; - char16_t* wchData = reinterpret_cast(pParams->wchData); - if (bSwapEndian) { - SwapUTF16Bytes(wchData, pParams->dwWchCount); + return false; + } + unsigned int uiParameterCount = readUInt32(&pbData[uiCurrentByte], bSwapEndian); + uiCurrentByte += sizeof(unsigned int); + bool bXMLVersion = false; + + for(unsigned int i = 0; i < uiParameterCount; ++i) + { + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, sizeof(C4JStorage::DLC_FILE_PARAM))) + { + return false; } - // Map DLC strings to application strings, then store the DLC index mapping to application index - wstring parameterName(static_cast(pParams->wchData)); + C4JStorage::DLC_FILE_PARAM *pParams = reinterpret_cast(&pbData[uiCurrentByte]); + unsigned int dwWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; + size_t paramSize = sizeof(C4JStorage::DLC_FILE_PARAM) + (dwWchCount * sizeof(WCHAR)); + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, paramSize)) + { + return false; + } + + pParams->dwType = bSwapEndian ? SwapInt32(pParams->dwType) : pParams->dwType; + pParams->dwWchCount = dwWchCount; + char16_t* wchData = reinterpret_cast(pParams->wchData); + if (bSwapEndian) + { + SwapUTF16Bytes(wchData, dwWchCount); + } + + wstring parameterName(reinterpret_cast(pParams->wchData), pParams->dwWchCount); EDLCParameterType type = getParameterType(parameterName); - if( type != e_DLCParamType_Invalid ) + if(type != e_DLCParamType_Invalid) { parameterMapping[pParams->dwType] = type; - - if (type == e_DLCParamType_XMLVersion) + if(type == e_DLCParamType_XMLVersion) { bXMLVersion = true; } } - uiCurrentByte+= sizeof(C4JStorage::DLC_FILE_PARAM)+(pParams->dwWchCount*sizeof(WCHAR)); - pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; + + uiCurrentByte += static_cast(paramSize); } - //ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); if (bXMLVersion) { - uiCurrentByte += sizeof(int); + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, sizeof(unsigned int))) + { + return false; + } + uiCurrentByte += sizeof(unsigned int); } - unsigned int uiFileCount=readUInt32(&pbData[uiCurrentByte], bSwapEndian); - uiCurrentByte+=sizeof(int); - C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; - - DWORD dwTemp=uiCurrentByte; - for(unsigned int i=0;idwWchCount = bSwapEndian ? SwapInt32(pFile->dwWchCount) : pFile->dwWchCount; - dwTemp+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR); - pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp]; + return false; } - PBYTE pbTemp=((PBYTE )pFile);//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; - pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; + unsigned int uiFileCount = readUInt32(&pbData[uiCurrentByte], bSwapEndian); + uiCurrentByte += sizeof(unsigned int); - for(unsigned int i=0;i(&pbData[uiCurrentByte]); + + DWORD dwTemp = uiCurrentByte; + for(unsigned int i = 0; i < uiFileCount; ++i) + { + if(!isValidDLCRange(pbData, dwLength, dwTemp, sizeof(C4JStorage::DLC_FILE_DETAILS))) + { + return false; + } + + pFile = reinterpret_cast(&pbData[dwTemp]); + unsigned int dwWchCount = bSwapEndian ? SwapInt32(pFile->dwWchCount) : pFile->dwWchCount; + size_t fileDetailsSize = sizeof(C4JStorage::DLC_FILE_DETAILS) + (dwWchCount * sizeof(WCHAR)); + if(!isValidDLCRange(pbData, dwLength, dwTemp, fileDetailsSize)) + { + return false; + } + + dwTemp += static_cast(fileDetailsSize); + } + + if(!isValidDLCRange(pbData, dwLength, dwTemp, 0)) + { + return false; + } + + PBYTE pbTemp = pbData + dwTemp; + pFile = reinterpret_cast(&pbData[uiCurrentByte]); + + for(unsigned int i = 0; i < uiFileCount; ++i) + { + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, sizeof(C4JStorage::DLC_FILE_DETAILS))) + { + return false; + } + + pFile = reinterpret_cast(&pbData[uiCurrentByte]); + unsigned int dwWchCount = bSwapEndian ? SwapInt32(pFile->dwWchCount) : pFile->dwWchCount; + unsigned int uiFileSize = bSwapEndian ? SwapInt32(pFile->uiFileSize) : pFile->uiFileSize; + size_t fileHeaderSize = sizeof(C4JStorage::DLC_FILE_DETAILS) + (dwWchCount * sizeof(WCHAR)); + if(!isValidDLCRange(pbData, dwLength, uiCurrentByte, fileHeaderSize)) + { + return false; + } + pFile->dwType = bSwapEndian ? SwapInt32(pFile->dwType) : pFile->dwType; - pFile->uiFileSize = bSwapEndian ? SwapInt32(pFile->uiFileSize) : pFile->uiFileSize; + pFile->uiFileSize = uiFileSize; char16_t* wchFile = reinterpret_cast(pFile->wchFile); - if (bSwapEndian) { - SwapUTF16Bytes(wchFile, pFile->dwWchCount); + if (bSwapEndian) + { + SwapUTF16Bytes(wchFile, dwWchCount); } EDLCType type = static_cast(pFile->dwType); @@ -670,43 +749,65 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dlcFile = pack->addFile(type,(WCHAR *)pFile->wchFile); } - // Params - uiParameterCount=readUInt32(pbTemp, bSwapEndian); - pbTemp+=sizeof(int); - pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; - for(unsigned int j=0;j(pbTemp - pbData), sizeof(unsigned int))) { - //DLCManager::EDLCParameterType paramType = DLCManager::e_DLCParamType_Invalid; + return false; + } + uiParameterCount = readUInt32(pbTemp, bSwapEndian); + pbTemp += sizeof(unsigned int); + C4JStorage::DLC_FILE_PARAM *pParams = reinterpret_cast(pbTemp); + for(unsigned int j = 0; j < uiParameterCount; ++j) + { + if(!isValidDLCRange(pbData, dwLength, static_cast(pbTemp - pbData), sizeof(C4JStorage::DLC_FILE_PARAM))) + { + return false; + } + + pParams = reinterpret_cast(pbTemp); + unsigned int dwParamWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; + size_t paramSize = sizeof(C4JStorage::DLC_FILE_PARAM) + (dwParamWchCount * sizeof(WCHAR)); + if(!isValidDLCRange(pbData, dwLength, static_cast(pbTemp - pbData), paramSize)) + { + return false; + } + pParams->dwType = bSwapEndian ? SwapInt32(pParams->dwType) : pParams->dwType; - pParams->dwWchCount = bSwapEndian ? SwapInt32(pParams->dwWchCount) : pParams->dwWchCount; + pParams->dwWchCount = dwParamWchCount; char16_t* wchData = reinterpret_cast(pParams->wchData); - if (bSwapEndian) { - SwapUTF16Bytes(wchData, pParams->dwWchCount); + if (bSwapEndian) + { + SwapUTF16Bytes(wchData, dwParamWchCount); } auto it = parameterMapping.find(pParams->dwType); - - if(it != parameterMapping.end() ) + if(it != parameterMapping.end()) { if(type == e_DLCType_PackConfig) { pack->addParameter(it->second,(WCHAR *)pParams->wchData); } - else + else if(dlcFile != nullptr) { - if(dlcFile != nullptr) dlcFile->addParameter(it->second,(WCHAR *)pParams->wchData); - else if(dlcTexturePack != nullptr) dlcTexturePack->addParameter(it->second, (WCHAR *)pParams->wchData); + dlcFile->addParameter(it->second,(WCHAR *)pParams->wchData); + } + else if(dlcTexturePack != nullptr) + { + dlcTexturePack->addParameter(it->second, (WCHAR *)pParams->wchData); } } - pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount); - pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; + + pbTemp += static_cast(paramSize); + } + + if(!isValidDLCRange(pbData, dwLength, static_cast(pbTemp - pbData), uiFileSize)) + { + return false; } - //pbTemp+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); if(dlcTexturePack != nullptr) { DWORD texturePackFilesProcessed = 0; - bool validPack = processDLCDataFile(texturePackFilesProcessed,pbTemp,pFile->uiFileSize,dlcTexturePack); + bool validPack = processDLCDataFile(texturePackFilesProcessed, pbTemp, uiFileSize, dlcTexturePack); pack->SetDataPointer(nullptr); // If it's a child pack, it doesn't own the data if(!validPack || texturePackFilesProcessed == 0) { @@ -726,8 +827,7 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } else if(dlcFile != nullptr) { - // Data - dlcFile->addData(pbTemp,pFile->uiFileSize); + dlcFile->addData(pbTemp, uiFileSize); // TODO - 4J Stu Remove the need for this vSkinNames vector, or manage it differently switch(pFile->dwType) @@ -740,14 +840,11 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD ++dwFilesProcessed; } - // Move the pointer to the start of the next files data; - pbTemp+=pFile->uiFileSize; - uiCurrentByte+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR); - - pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; + pbTemp += uiFileSize; + uiCurrentByte += static_cast(fileHeaderSize); } - if( pack->getDLCItemsCount(e_DLCType_GameRules) > 0 + if(pack->getDLCItemsCount(e_DLCType_GameRules) > 0 || pack->getDLCItemsCount(e_DLCType_GameRulesHeader) > 0) { app.m_gameRules.loadGameRules(pack); diff --git a/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu480.swf b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu480.swf new file mode 100644 index 00000000..26df9a49 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu480.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu720.swf b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu720.swf new file mode 100644 index 00000000..cdd6849f Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenu720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuSplit720.swf b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuSplit720.swf new file mode 100644 index 00000000..be8993c6 Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuSplit720.swf differ diff --git a/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuVita.swf b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuVita.swf new file mode 100644 index 00000000..6027b19b Binary files /dev/null and b/Minecraft.Client/Common/Media/MediaWindows64/HelpAndOptionsMenuVita.swf differ diff --git a/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_N.png b/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_N.png new file mode 100644 index 00000000..49fe3351 Binary files /dev/null and b/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_N.png differ diff --git a/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_S.png b/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_S.png new file mode 100644 index 00000000..2c418e89 Binary files /dev/null and b/Minecraft.Client/Windows64Media/DLC/Mario/Data/ControlType/Panorama/Panorama_S.png differ diff --git a/Minecraft.Client/Windows64Media/DLC/Mario/TexturePack.pck b/Minecraft.Client/Windows64Media/DLC/Mario/TexturePack.pck index 778952c4..84311783 100644 Binary files a/Minecraft.Client/Windows64Media/DLC/Mario/TexturePack.pck and b/Minecraft.Client/Windows64Media/DLC/Mario/TexturePack.pck differ