Address remaining review feedback on buffer reads

This commit is contained in:
notmatthewbeshay 2026-03-13 20:11:00 +11:00
parent 883e98bde0
commit 00d65b8487
6 changed files with 142 additions and 65 deletions

View file

@ -38,6 +38,7 @@
#include "../Minecraft.World/IO/Streams/InputOutputStream.h"
#include "../Minecraft.World/Level/Storage/LevelSettings.h"
#include "../Minecraft.Client/Player/User.h"
#include <cstring>
#include "../Minecraft.World/Level/LevelData.h"
#include "../Minecraft.World/Headers/net.minecraft.world.entity.player.h"
#include "../Minecraft.Client/Rendering/EntityRenderers/EntityRenderDispatcher.h"
@ -7649,6 +7650,13 @@ unsigned int CMinecraftApp::FromBigEndian(unsigned int uiValue)
void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int imageBytes, unsigned char *seedText, unsigned int &uiHostOptions, bool &bHostOptionsRead, std::uint32_t &uiTexturePack)
{
auto readPngUInt32 = [](const std::uint8_t *data) -> unsigned int
{
unsigned int value = 0;
std::memcpy(&value, data, sizeof(value));
return value;
};
std::uint8_t *ucPtr = imageData;
unsigned int uiCount=0;
unsigned int uiChunkLen;
@ -7666,11 +7674,9 @@ void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int image
while(uiCount < imageBytes)
{
uiChunkLen=*(unsigned int *)&ucPtr[uiCount];
uiChunkLen=FromBigEndian(uiChunkLen);
uiChunkLen = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
uiCount+=sizeof(int);
uiChunkType=*(unsigned int *)&ucPtr[uiCount];
uiChunkType=FromBigEndian(uiChunkType);
uiChunkType = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
uiCount+=sizeof(int);
if(uiChunkType==PNG_TAG_tEXt) // tEXt
@ -7735,8 +7741,7 @@ void CMinecraftApp::GetImageTextData(std::uint8_t *imageData, unsigned int image
}
}
uiCount+=uiChunkLen;
uiCRC=*(unsigned int*)&ucPtr[uiCount];
uiCRC=FromBigEndian(uiCRC);
uiCRC = FromBigEndian(readPngUInt32(&ucPtr[uiCount]));
uiCount+=sizeof(int);
}

View file

@ -1,4 +1,7 @@
#include "../../Minecraft.World/Platform/stdafx.h"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include "DLCManager.h"
#include "DLCAudioFile.h"
#if defined _XBOX || defined _WINDOWS64
@ -6,6 +9,64 @@
#include "../../Minecraft.Client/Platform/Xbox/XML/xmlFilesCallback.h"
#endif
namespace
{
constexpr std::size_t AUDIO_DLC_WCHAR_BIN_SIZE = 2;
#if WCHAR_MAX > 0xFFFF
static std::wstring ReadAudioDlcWString(const void *data)
{
const std::uint16_t *chars = static_cast<const std::uint16_t *>(data);
const std::uint16_t *end = chars;
while(*end != 0)
{
++end;
}
std::wstring out(static_cast<std::size_t>(end - chars), 0);
for(std::size_t i = 0; i < out.size(); ++i)
{
out[i] = static_cast<wchar_t>(chars[i]);
}
return out;
}
#else
static std::wstring ReadAudioDlcWString(const void *data)
{
return std::wstring(static_cast<const wchar_t *>(data));
}
#endif
template <typename T>
T ReadAudioDlcValue(const std::uint8_t *data, unsigned int offset = 0)
{
T value;
std::memcpy(&value, data + offset, sizeof(value));
return value;
}
template <typename T>
void ReadAudioDlcStruct(T *out, const std::uint8_t *data, unsigned int offset = 0)
{
std::memcpy(out, data + offset, sizeof(*out));
}
inline unsigned int AudioParamAdvance(unsigned int wcharCount)
{
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_PARAM) + wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
}
inline unsigned int AudioDetailAdvance(unsigned int wcharCount)
{
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_DETAILS) + wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
}
inline std::wstring ReadAudioParamString(const std::uint8_t *data, unsigned int offset)
{
return ReadAudioDlcWString(data + offset + offsetof(C4JStorage::DLC_FILE_PARAM, wchData));
}
}
DLCAudioFile::DLCAudioFile(const std::wstring &path) : DLCFile(DLCManager::e_DLCType_Audio,path)
{
m_pbData = NULL;
@ -128,7 +189,7 @@ bool DLCAudioFile::processDLCDataFile(std::uint8_t *pbData, std::uint32_t dataLe
// File format defined in the AudioPacker
// File format: Version 1
unsigned int uiVersion=*(unsigned int *)pbData;
unsigned int uiVersion = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
if(uiVersion < CURRENT_AUDIO_VERSION_NUM)
@ -138,60 +199,62 @@ bool DLCAudioFile::processDLCDataFile(std::uint8_t *pbData, std::uint32_t dataLe
return false;
}
unsigned int uiParameterTypeCount=*(unsigned int *)&pbData[uiCurrentByte];
unsigned int uiParameterTypeCount = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
C4JStorage::DLC_FILE_PARAM paramBuf;
ReadAudioDlcStruct(&paramBuf, pbData, uiCurrentByte);
for(unsigned int i=0;i<uiParameterTypeCount;i++)
{
// Map DLC strings to application strings, then store the DLC index mapping to application index
std::wstring parameterName((WCHAR *)pParams->wchData);
std::wstring parameterName = ReadAudioParamString(pbData, uiCurrentByte);
EAudioParameterType type = getParameterType(parameterName);
if( type != e_AudioParamType_Invalid )
{
parameterMapping[pParams->dwType] = type;
parameterMapping[paramBuf.dwType] = type;
}
uiCurrentByte+= sizeof(C4JStorage::DLC_FILE_PARAM)+(pParams->dwWchCount*sizeof(WCHAR));
pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
uiCurrentByte += AudioParamAdvance(paramBuf.dwWchCount);
ReadAudioDlcStruct(&paramBuf, pbData, uiCurrentByte);
}
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte];
unsigned int uiFileCount = ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
C4JStorage::DLC_FILE_DETAILS fileBuf;
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
unsigned int tempByteOffset = uiCurrentByte;
for(unsigned int i=0;i<uiFileCount;i++)
{
tempByteOffset += sizeof(C4JStorage::DLC_FILE_DETAILS) + pFile->dwWchCount * sizeof(WCHAR);
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[tempByteOffset];
tempByteOffset += AudioDetailAdvance(fileBuf.dwWchCount);
ReadAudioDlcStruct(&fileBuf, pbData, tempByteOffset);
}
std::uint8_t *pbTemp = reinterpret_cast<std::uint8_t *>(pFile);
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
std::uint8_t *pbTemp = &pbData[tempByteOffset];
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
for(unsigned int i=0;i<uiFileCount;i++)
{
EAudioType type = (EAudioType)pFile->dwType;
EAudioType type = (EAudioType)fileBuf.dwType;
// Params
unsigned int uiParameterCount=*(unsigned int *)pbTemp;
unsigned int uiParameterCount = ReadAudioDlcValue<unsigned int>(pbTemp);
pbTemp+=sizeof(int);
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
ReadAudioDlcStruct(&paramBuf, pbTemp);
for(unsigned int j=0;j<uiParameterCount;j++)
{
//EAudioParameterType paramType = e_AudioParamType_Invalid;
AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
AUTO_VAR(it, parameterMapping.find(paramBuf.dwType));
if(it != parameterMapping.end() )
{
addParameter(type,(EAudioParameterType)pParams->dwType,(WCHAR *)pParams->wchData);
addParameter(type, (EAudioParameterType)paramBuf.dwType, ReadAudioParamString(pbTemp, 0));
}
pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount);
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
pbTemp += AudioParamAdvance(paramBuf.dwWchCount);
ReadAudioDlcStruct(&paramBuf, pbTemp);
}
// Move the pointer to the start of the next files data;
pbTemp+=pFile->uiFileSize;
uiCurrentByte+=sizeof(C4JStorage::DLC_FILE_DETAILS)+pFile->dwWchCount*sizeof(WCHAR);
pbTemp += fileBuf.uiFileSize;
uiCurrentByte += AudioDetailAdvance(fileBuf.dwWchCount);
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
}

View file

@ -7,6 +7,7 @@
#include "../../Minecraft.World/Util/PortableFileIO.h"
#include "../../Minecraft.Client/Minecraft.h"
#include "../../Minecraft.Client/Textures/Packs/TexturePackRepository.h"
#include <cstring>
#include <limits>
#include <cstddef>
#include <cstdint>
@ -57,6 +58,20 @@ static_assert( sizeof(wchar_t) == 2, "How did we get here? wide char smaller tha
namespace
{
template <typename T>
T ReadDlcValue(const std::uint8_t *data, unsigned int offset = 0)
{
T value;
std::memcpy(&value, data + offset, sizeof(value));
return value;
}
template <typename T>
void ReadDlcStruct(T *out, const std::uint8_t *data, unsigned int offset = 0)
{
std::memcpy(out, data + offset, sizeof(*out));
}
std::wstring getMountedDlcReadPath(const std::string &path)
{
std::wstring readPath = convStringToWstring(path);
@ -680,7 +695,7 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
// // 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=*(unsigned int *)pbData;
unsigned int uiVersion = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
if(uiVersion < CURRENT_DLC_VERSION_NUM)
@ -689,46 +704,48 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
return 0;
}
pack->SetDataPointer(pbData);
unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte];
unsigned int uiParameterCount = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
C4JStorage::DLC_FILE_PARAM paramBuf;
ReadDlcStruct(&paramBuf, pbData, uiCurrentByte);
for(unsigned int i=0;i<uiParameterCount;i++)
{
// Map DLC strings to application strings, then store the DLC index mapping to application index
std::wstring parameterName = DLC_WSTRING(pParams->wchData);
std::wstring parameterName = DLC_PARAM_WSTR(pbData, uiCurrentByte);
DLCManager::EDLCParameterType type = DLCManager::getParameterType(parameterName);
if( type != DLCManager::e_DLCParamType_Invalid )
{
parameterMapping[pParams->dwType] = type;
parameterMapping[paramBuf.dwType] = type;
}
uiCurrentByte+= DLC_PARAM_ADV(pParams->dwWchCount);
pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte];
uiCurrentByte += DLC_PARAM_ADV(paramBuf.dwWchCount);
ReadDlcStruct(&paramBuf, pbData, uiCurrentByte);
}
unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte];
unsigned int uiFileCount = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte+=sizeof(int);
C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
C4JStorage::DLC_FILE_DETAILS fileBuf;
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
unsigned int dwTemp=uiCurrentByte;
for(unsigned int i=0;i<uiFileCount;i++)
{
dwTemp+=DLC_DETAIL_ADV(pFile->dwWchCount);
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp];
dwTemp += DLC_DETAIL_ADV(fileBuf.dwWchCount);
ReadDlcStruct(&fileBuf, pbData, dwTemp);
}
std::uint8_t *pbTemp = reinterpret_cast<std::uint8_t *>(pFile);
pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
std::uint8_t *pbTemp = &pbData[dwTemp];
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
for(unsigned int i=0;i<uiFileCount;i++)
{
DLCManager::EDLCType type = (DLCManager::EDLCType)pFile->dwType;
DLCManager::EDLCType type = (DLCManager::EDLCType)fileBuf.dwType;
// Params
uiParameterCount=*(unsigned int *)pbTemp;
uiParameterCount = ReadDlcValue<unsigned int>(pbTemp);
pbTemp+=sizeof(int);
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
ReadDlcStruct(&paramBuf, pbTemp);
for(unsigned int j=0;j<uiParameterCount;j++)
{
AUTO_VAR(it, parameterMapping.find( pParams->dwType ));
AUTO_VAR(it, parameterMapping.find(paramBuf.dwType));
if(it != parameterMapping.end() )
{
@ -736,7 +753,7 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
{
if(it->second==e_DLCParamType_PackId)
{
std::wstring wsTemp = DLC_WSTRING(pParams->wchData);
std::wstring wsTemp = DLC_PARAM_WSTR(pbTemp, 0);
std::wstringstream ss;
// 4J Stu - numbered using decimal to make it easier for artists/people to number manually
ss << std::dec << wsTemp.c_str();
@ -746,16 +763,16 @@ std::uint32_t DLCManager::retrievePackID(std::uint8_t *pbData, unsigned int dwLe
}
}
}
pbTemp+=DLC_PARAM_ADV(pParams->dwWchCount);
pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp;
pbTemp += DLC_PARAM_ADV(paramBuf.dwWchCount);
ReadDlcStruct(&paramBuf, pbTemp);
}
if(bPackIDSet) break;
// Move the pointer to the start of the next files data;
pbTemp+=pFile->uiFileSize;
uiCurrentByte+=DLC_DETAIL_ADV(pFile->dwWchCount);
pbTemp += fileBuf.uiFileSize;
uiCurrentByte += DLC_DETAIL_ADV(fileBuf.dwWchCount);
pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte];
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
}
parameterMapping.clear();

View file

@ -82,7 +82,7 @@ void AddPlayerPacket::read(DataInputStream *dis) //throws IOException
m_skinId = static_cast<std::uint32_t>(dis->readInt());
m_capeId = static_cast<std::uint32_t>(dis->readInt());
INT privileges = dis->readInt();
m_uiGamePrivileges = *(unsigned int *)&privileges;
m_uiGamePrivileges = static_cast<unsigned int>(privileges);
MemSect(1);
unpack = SynchedEntityData::unpack(dis);
MemSect(0);

View file

@ -1,5 +1,4 @@
#include "../../Platform/stdafx.h"
#include <cstring>
#include <iostream>
#include "../../IO/Streams/InputOutputStream.h"
#include "../../Headers/net.minecraft.world.entity.h"
@ -32,17 +31,14 @@ TextureAndGeometryChangePacket::TextureAndGeometryChangePacket(std::shared_ptr<E
void TextureAndGeometryChangePacket::read(DataInputStream *dis) //throws IOException
{
id = dis->readInt();
int skinId = dis->readInt();
std::memcpy(&dwSkinID, &skinId, sizeof(dwSkinID));
dwSkinID = static_cast<std::uint32_t>(dis->readInt());
path = dis->readUTF();
}
void TextureAndGeometryChangePacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeInt(id);
int skinId = 0;
std::memcpy(&skinId, &dwSkinID, sizeof(dwSkinID));
dos->writeInt(skinId);
dos->writeInt(static_cast<int>(dwSkinID));
dos->writeUTF(path);
}

View file

@ -1,5 +1,4 @@
#include "../../Platform/stdafx.h"
#include <cstring>
#include <iostream>
#include "../../IO/Streams/InputOutputStream.h"
#include "PacketListener.h"
@ -123,8 +122,7 @@ void TextureAndGeometryPacket::handle(PacketListener *listener)
void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
{
textureName = dis->readUTF();
int skinId = dis->readInt();
std::memcpy(&dwSkinID, &skinId, sizeof(dwSkinID));
dwSkinID = static_cast<std::uint32_t>(dis->readInt());
dwTextureBytes = (std::uint32_t)dis->readShort();
if(dwTextureBytes>0)
@ -162,9 +160,7 @@ void TextureAndGeometryPacket::read(DataInputStream *dis) //throws IOException
void TextureAndGeometryPacket::write(DataOutputStream *dos) //throws IOException
{
dos->writeUTF(textureName);
int skinId = 0;
std::memcpy(&skinId, &dwSkinID, sizeof(dwSkinID));
dos->writeInt(skinId);
dos->writeInt(static_cast<int>(dwSkinID));
dos->writeShort((short)dwTextureBytes);
for(std::uint32_t i=0;i<dwTextureBytes;i++)
{