From 026a448e3231444dedd6b0dd3ec35c1155287db9 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 22 Jul 2018 22:14:27 +1000 Subject: [PATCH] Cleanup stream API a bit in C client --- ClassicalSharp/TexturePack/ZipReader.cs | 10 ++--- src/Client/Bitmap.c | 8 ++-- src/Client/Bitmap.h | 4 +- src/Client/Formats.c | 51 +++++++++---------------- src/Client/PacketHandlers.c | 40 +++++++++---------- src/Client/Stream.c | 30 +++++---------- src/Client/Stream.h | 15 ++------ src/Client/TexturePack.c | 38 ++++++++---------- src/Client/TexturePack.h | 2 +- 9 files changed, 74 insertions(+), 124 deletions(-) diff --git a/ClassicalSharp/TexturePack/ZipReader.cs b/ClassicalSharp/TexturePack/ZipReader.cs index 3d7391417..562bd5744 100644 --- a/ClassicalSharp/TexturePack/ZipReader.cs +++ b/ClassicalSharp/TexturePack/ZipReader.cs @@ -79,8 +79,8 @@ namespace ClassicalSharp.Textures { } void ReadLocalFileHeader(BinaryReader reader, ZipEntry entry) { - ushort versionNeeded = reader.ReadUInt16(); - ushort flags = reader.ReadUInt16(); + reader.ReadUInt16(); // version needed + reader.ReadUInt16(); // flags ushort compressionMethod = reader.ReadUInt16(); reader.ReadUInt32(); // last modified reader.ReadUInt32(); // CRC32 @@ -96,12 +96,8 @@ namespace ClassicalSharp.Textures { if (SelectZipEntry != null && !SelectZipEntry(fileName)) return; reader.ReadBytes(extraFieldLen); - if (versionNeeded > 20) - Utils.LogDebug("May not be able to properly extract a .zip enty with a version later than 2.0"); - byte[] data = DecompressEntry(reader, compressionMethod, compressedSize, uncompressedSize); - if (data != null) - ProcessZipEntry(fileName, data, entry); + if (data != null) ProcessZipEntry(fileName, data, entry); } void ReadCentralDirectory(BinaryReader reader, ZipEntry[] entries) { diff --git a/src/Client/Bitmap.c b/src/Client/Bitmap.c index 6525a7201..297887f39 100644 --- a/src/Client/Bitmap.c +++ b/src/Client/Bitmap.c @@ -451,11 +451,9 @@ ReturnCode Bitmap_DecodePng(struct Bitmap* bmp, struct Stream* stream) { if (dataSize != 0) return PNG_ERR_INVALID_END_SIZE; } break; - default: { - ReturnCode result = Stream_Skip(stream, dataSize); - if (result != 0) return PNG_ERR_SKIPPING_CHUNK; - } break; - } + default: + Stream_Skip(stream, dataSize); + break; Stream_ReadU32_BE(stream); /* Skip CRC32 */ } diff --git a/src/Client/Bitmap.h b/src/Client/Bitmap.h index 22e9c2fdb..fac53703d 100644 --- a/src/Client/Bitmap.h +++ b/src/Client/Bitmap.h @@ -29,10 +29,10 @@ bool Bitmap_DetectPng(UInt8* data, UInt32 len); enum PNG_ERR { PNG_ERR_INVALID_SIG = 307001, PNG_ERR_INVALID_HEADER_SIZE, PNG_ERR_TOO_WIDE, PNG_ERR_TOO_TALL, - PNG_ERR_INVALID_BPP, PNG_ERR_INVALID_COL, PNG_ERR_INVALID_COL_BPP, + PNG_ERR_INVALID_BPP, PNG_ERR_INVALID_COL, PNG_ERR_INVALID_COL_BPP, PNG_ERR_COMP_METHOD, PNG_ERR_FILTER, PNG_ERR_INTERLACED, PNG_ERR_PAL_ENTRIES, PNG_ERR_PAL_SIZE, PNG_ERR_TRANS_COUNT, PNG_ERR_TRANS_INVALID, - PNG_ERR_INVALID_END_SIZE, PNG_ERR_SKIPPING_CHUNK, + PNG_ERR_INVALID_END_SIZE, }; /* Partially based off information from diff --git a/src/Client/Formats.c b/src/Client/Formats.c index bfde146be..979ed45ad 100644 --- a/src/Client/Formats.c +++ b/src/Client/Formats.c @@ -110,14 +110,14 @@ void Lvl_Load(struct Stream* stream) { World_Height = Stream_ReadU16_LE(&compStream); struct LocalPlayer* p = &LocalPlayer_Instance; - p->Spawn.X = (Real32)Stream_ReadU16_LE(&compStream); - p->Spawn.Z = (Real32)Stream_ReadU16_LE(&compStream); - p->Spawn.Y = (Real32)Stream_ReadU16_LE(&compStream); + p->Spawn.X = Stream_ReadU16_LE(&compStream); + p->Spawn.Z = Stream_ReadU16_LE(&compStream); + p->Spawn.Y = Stream_ReadU16_LE(&compStream); p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(&compStream)); p->SpawnHeadX = Math_Packed2Deg(Stream_ReadU8(&compStream)); if (header == LVL_VERSION) { - Stream_ReadU16_LE(&compStream); /* pervisit and perbuild perms */ + Stream_Skip(&compStream, 1 + 1); /* permissions: (1) pervisit, (1) perbuild */ } Map_ReadBlocks(&compStream); @@ -134,9 +134,7 @@ void Lvl_Load(struct Stream* stream) { #define FCM_IDENTIFIER 0x0FC2AF40UL #define FCM_REVISION 13 static void Fcm_ReadString(struct Stream* stream) { - UInt16 length = Stream_ReadU16_LE(stream); - ReturnCode code = Stream_Skip(stream, length); - ErrorHandler_CheckOrFail(code, "FCM import - skipping string"); + Stream_Skip(stream, Stream_ReadU16_LE(stream)); } void Fcm_Load(struct Stream* stream) { @@ -152,10 +150,10 @@ void Fcm_Load(struct Stream* stream) { World_Height = Stream_ReadU16_LE(stream); struct LocalPlayer* p = &LocalPlayer_Instance; - p->Spawn.X = Stream_ReadI32_LE(stream) / 32.0f; - p->Spawn.Y = Stream_ReadI32_LE(stream) / 32.0f; - p->Spawn.Z = Stream_ReadI32_LE(stream) / 32.0f; - p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(stream)); + p->Spawn.X = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f; + p->Spawn.Y = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f; + p->Spawn.Z = ((Int32)Stream_ReadU32_LE(stream)) / 32.0f; + p->SpawnRotY = Math_Packed2Deg(Stream_ReadU8(stream)); p->SpawnHeadX = Math_Packed2Deg(Stream_ReadU8(stream)); UInt8 tmp[26]; @@ -210,9 +208,7 @@ struct NbtTag { UInt8 Value_U8; Int16 Value_I16; Int32 Value_I32; - Int64 Value_I64; Real32 Value_R32; - Real64 Value_R64; UInt8 DataSmall[String_BufferSize(NBT_SMALL_SIZE)]; UInt8* DataBig; /* malloc for big byte arrays */ }; @@ -233,21 +229,11 @@ static Int32 NbtTag_I32(struct NbtTag* tag) { return tag->Value_I32; } -static Int64 NbtTag_I64(struct NbtTag* tag) { - if (tag->TagID != NBT_TAG_INT64) { ErrorHandler_Fail("Expected I64 NBT tag"); } - return tag->Value_I64; -} - static Real32 NbtTag_R32(struct NbtTag* tag) { if (tag->TagID != NBT_TAG_REAL32) { ErrorHandler_Fail("Expected R32 NBT tag"); } return tag->Value_R32; } -static Real64 NbtTag_R64(struct NbtTag* tag) { - if (tag->TagID != NBT_TAG_REAL64) { ErrorHandler_Fail("Expected R64 NBT tag"); } - return tag->Value_R64; -} - static UInt8 NbtTag_U8_At(struct NbtTag* tag, Int32 i) { if (tag->TagID != NBT_TAG_INT8_ARRAY) { ErrorHandler_Fail("Expected I8_Array NBT tag"); } if (i >= tag->DataSize) { ErrorHandler_Fail("Tried to access past bounds of I8_Array tag"); } @@ -293,13 +279,12 @@ static void Nbt_ReadTag(UInt8 typeId, bool readTagName, struct Stream* stream, s case NBT_TAG_INT32: tag.Value_I32 = Stream_ReadI32_BE(stream); break; case NBT_TAG_INT64: - tag.Value_I64 = Stream_ReadI64_BE(stream); break; + Stream_Skip(stream, 8); break; /* (8) data */ case NBT_TAG_REAL32: /* TODO: Is this union abuse even legal */ tag.Value_I32 = Stream_ReadI32_BE(stream); break; case NBT_TAG_REAL64: - /* TODO: Is this union abuse even legal */ - tag.Value_I64 = Stream_ReadI64_BE(stream); break; + Stream_Skip(stream, 8); break; /* (8) data */ case NBT_TAG_INT8_ARRAY: count = Stream_ReadU32_BE(stream); @@ -617,9 +602,8 @@ struct JFieldDesc { UInt8 Type; UChar FieldName[String_BufferSize(JNAME_SIZE)]; union { - Int8 Value_I8; + UInt8 Value_U8; Int32 Value_I32; - Int64 Value_I64; Real32 Value_R32; struct { UInt8* Value_Ptr; UInt32 Value_Size; }; }; @@ -649,7 +633,7 @@ static void Dat_ReadFieldDesc(struct Stream* stream, struct JFieldDesc* desc) { UChar className1[String_BufferSize(JNAME_SIZE)]; Dat_ReadString(stream, className1); } else if (typeCode == TC_REFERENCE) { - Stream_ReadI32_BE(stream); /* handle */ + Stream_Skip(stream, 4); /* (4) handle */ } else { ErrorHandler_Fail("Unsupported type code in FieldDesc class name"); } @@ -662,8 +646,7 @@ static void Dat_ReadClassDesc(struct Stream* stream, struct JClassDesc* desc) { if (typeCode != TC_CLASSDESC) ErrorHandler_Fail("Unsupported type code in ClassDesc header"); Dat_ReadString(stream, desc->ClassName); - Stream_ReadU64_BE(stream); /* serial version UID */ - Stream_ReadU8(stream); /* flags */ + Stream_Skip(stream, 8 + 1); /* (8) serial version UID, (1) flags */ desc->FieldsCount = Stream_ReadU16_BE(stream); if (desc->FieldsCount > Array_Elems(desc->Fields)) ErrorHandler_Fail("ClassDesc has too many fields"); @@ -681,14 +664,14 @@ static void Dat_ReadClassDesc(struct Stream* stream, struct JClassDesc* desc) { static void Dat_ReadFieldData(struct Stream* stream, struct JFieldDesc* field) { switch (field->Type) { case JFIELD_INT8: - field->Value_I8 = Stream_ReadI8(stream); break; + field->Value_U8 = Stream_ReadU8(stream); break; case JFIELD_REAL32: /* TODO: Is this union abuse even legal */ field->Value_I32 = Stream_ReadI32_BE(stream); break; case JFIELD_INT32: field->Value_I32 = Stream_ReadI32_BE(stream); break; case JFIELD_INT64: - field->Value_I64 = Stream_ReadI64_BE(stream); break; + Stream_Skip(stream, 8); break; /* (8) data */ case JFIELD_BOOL: field->Value_I32 = Stream_ReadU8(stream) != 0; break; @@ -746,7 +729,7 @@ void Dat_Load(struct Stream* stream) { Inflate_MakeStream(&compStream, &state, stream); /* .dat header */ - if (Stream_ReadI32_BE(&compStream) != 0x271BB788 || Stream_ReadU8(&compStream) != 0x02) { + if (Stream_ReadU32_BE(&compStream) != 0x271BB788 || Stream_ReadU8(&compStream) != 0x02) { ErrorHandler_Fail("Unexpected constant in .dat file"); } diff --git a/src/Client/PacketHandlers.c b/src/Client/PacketHandlers.c index 2e5ea1578..bea0d8ead 100644 --- a/src/Client/PacketHandlers.c +++ b/src/Client/PacketHandlers.c @@ -512,9 +512,9 @@ static void Classic_EntityTeleport(struct Stream* stream) { static void Classic_RelPosAndOrientationUpdate(struct Stream* stream) { EntityID id = Stream_ReadU8(stream); Vector3 pos; - pos.X = Stream_ReadI8(stream) / 32.0f; - pos.Y = Stream_ReadI8(stream) / 32.0f; - pos.Z = Stream_ReadI8(stream) / 32.0f; + pos.X = ((Int8)Stream_ReadU8(stream)) / 32.0f; + pos.Y = ((Int8)Stream_ReadU8(stream)) / 32.0f; + pos.Z = ((Int8)Stream_ReadU8(stream)) / 32.0f; Real32 rotY = Math_Packed2Deg(Stream_ReadU8(stream)); Real32 headX = Math_Packed2Deg(Stream_ReadU8(stream)); @@ -525,9 +525,9 @@ static void Classic_RelPosAndOrientationUpdate(struct Stream* stream) { static void Classic_RelPositionUpdate(struct Stream* stream) { EntityID id = Stream_ReadU8(stream); Vector3 pos; - pos.X = Stream_ReadI8(stream) / 32.0f; - pos.Y = Stream_ReadI8(stream) / 32.0f; - pos.Z = Stream_ReadI8(stream) / 32.0f; + pos.X = ((Int8)Stream_ReadU8(stream)) / 32.0f; + pos.Y = ((Int8)Stream_ReadU8(stream)) / 32.0f; + pos.Z = ((Int8)Stream_ReadU8(stream)) / 32.0f; struct LocationUpdate update; LocationUpdate_MakePos(&update, pos, true); Handlers_UpdateLocation(id, &update, true); @@ -749,7 +749,7 @@ static void CPE_ExtInfo(struct Stream* stream) { /* Workaround for old MCGalaxy that send ExtEntry sync but ExtInfo async. This means ExtEntry may sometimes arrive before ExtInfo, thus have to use += instead of = */ - cpe_serverExtensionsCount += Stream_ReadI16_BE(stream); + cpe_serverExtensionsCount += Stream_ReadU16_BE(stream); CPE_SendCpeExtInfoReply(); } @@ -827,9 +827,9 @@ static void CPE_SetTextHotkey(struct Stream* stream) { String label = Handlers_ReadString(stream, labelBuffer); String action = Handlers_ReadString(stream, actionBuffer); - Int32 keyCode = Stream_ReadI32_BE(stream); - UInt8 keyMods = Stream_ReadU8(stream); - if (keyCode < 0 || keyCode > 255) return; + UInt32 keyCode = Stream_ReadU32_BE(stream); + UInt8 keyMods = Stream_ReadU8(stream); + if (keyCode > 255) return; Key key = Hotkeys_LWJGL[keyCode]; if (key == Key_None) return; @@ -850,7 +850,7 @@ static void CPE_ExtAddPlayerName(struct Stream* stream) { UChar listNameBuffer[String_BufferSize(STRING_SIZE)]; UChar groupNameBuffer[String_BufferSize(STRING_SIZE)]; - Int32 id = Stream_ReadI16_BE(stream) & 0xFF; + Int32 id = Stream_ReadU16_BE(stream) & 0xFF; String playerName = Handlers_ReadString(stream, playerNameBuffer); String listName = Handlers_ReadString(stream, listNameBuffer); String groupName = Handlers_ReadString(stream, groupNameBuffer); @@ -879,7 +879,7 @@ static void CPE_ExtAddEntity(struct Stream* stream) { } static void CPE_ExtRemovePlayerName(struct Stream* stream) { - Int32 id = Stream_ReadI16_BE(stream) & 0xFF; + Int32 id = Stream_ReadU16_BE(stream) & 0xFF; Handlers_RemoveTablistEntry((EntityID)id); } @@ -899,10 +899,10 @@ static void CPE_MakeSelection(struct Stream* stream) { p2.Z = Stream_ReadI16_BE(stream); PackedCol col; - col.R = (UInt8)Stream_ReadI16_BE(stream); - col.G = (UInt8)Stream_ReadI16_BE(stream); - col.B = (UInt8)Stream_ReadI16_BE(stream); - col.A = (UInt8)Stream_ReadI16_BE(stream); + col.R = (UInt8)Stream_ReadU16_BE(stream); + col.G = (UInt8)Stream_ReadU16_BE(stream); + col.B = (UInt8)Stream_ReadU16_BE(stream); + col.A = (UInt8)Stream_Readu16_BE(stream); Selections_Add(selectionId, p1, p2, col); } @@ -914,10 +914,10 @@ static void CPE_RemoveSelection(struct Stream* stream) { static void CPE_SetEnvCol(struct Stream* stream) { UInt8 variable = Stream_ReadU8(stream); - Int16 r = Stream_ReadI16_BE(stream); - Int16 g = Stream_ReadI16_BE(stream); - Int16 b = Stream_ReadI16_BE(stream); - bool invalid = r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255; + UInt16 r = Stream_ReadU16_BE(stream); + UInt16 g = Stream_ReadU16_BE(stream); + UInt16 b = Stream_ReadU16_BE(stream); + bool invalid = r > 255 || g > 255 || b > 255; PackedCol col = PACKEDCOL_CONST((UInt8)r, (UInt8)g, (UInt8)b, 255); if (variable == 0) { diff --git a/src/Client/Stream.c b/src/Client/Stream.c index 4aa4b3bc6..a93d6d415 100644 --- a/src/Client/Stream.c +++ b/src/Client/Stream.c @@ -69,20 +69,21 @@ void Stream_SetName(struct Stream* stream, STRING_PURE String* name) { String_AppendString(&stream->Name, name); } -ReturnCode Stream_Skip(struct Stream* stream, UInt32 count) { - ReturnCode code = stream->Seek(stream, count, STREAM_SEEKFROM_CURRENT); - if (code == 0) return 0; - UInt8 tmp[4096]; +void Stream_Skip(struct Stream* stream, UInt32 count) { + ReturnCode result = stream->Seek(stream, count, STREAM_SEEKFROM_CURRENT); + if (result == 0) return; + UInt8 tmp[3584]; /* not quite 4 KB to avoid chkstk call */ - while (count > 0) { + while (count) { UInt32 toRead = min(count, sizeof(tmp)), read; - code = stream->Read(stream, tmp, toRead, &read); + result = stream->Read(stream, tmp, toRead, &read); - if (code != 0) return code; + if (result != 0) Stream_Fail(stream, result, "Skipping data from"); if (read == 0) break; /* end of stream */ count -= read; } - return count > 0; + + if (count) Stream_Fail(stream, 0, "Skipping data from"); } static ReturnCode Stream_DefaultIO(struct Stream* stream, UInt8* data, UInt32 count, UInt32* modified) { @@ -307,25 +308,12 @@ UInt32 Stream_ReadU32_BE(struct Stream* stream) { ((UInt32)buffer[2] << 8) | (UInt32)buffer[3]); } -UInt64 Stream_ReadU64_BE(struct Stream* stream) { - /* infrequently called, so not bothering to optimise this. */ - UInt32 hi = Stream_ReadU32_BE(stream); - UInt32 lo = Stream_ReadU32_LE(stream); - return (UInt64)(((UInt64)hi) << 32) | ((UInt64)lo); -} - void Stream_WriteU8(struct Stream* stream, UInt8 value) { UInt32 write; /* Inline 8 bit writing, because it is very frequently used. */ Stream_SafeWriteBlock(stream, &value, sizeof(UInt8), write); } -void Stream_WriteU16_LE(struct Stream* stream, UInt16 value) { - UInt8 buffer[sizeof(UInt16)]; - buffer[0] = (UInt8)(value ); buffer[1] = (UInt8)(value >> 8 ); - Stream_Write(stream, buffer, sizeof(UInt16)); -} - void Stream_WriteU16_BE(struct Stream* stream, UInt16 value) { UInt8 buffer[sizeof(UInt16)]; buffer[0] = (UInt8)(value >> 8 ); buffer[1] = (UInt8)(value ); diff --git a/src/Client/Stream.h b/src/Client/Stream.h index 0662f4900..bc826666e 100644 --- a/src/Client/Stream.h +++ b/src/Client/Stream.h @@ -50,7 +50,7 @@ void Stream_Write(struct Stream* stream, UInt8* buffer, UInt32 count); ReturnCode Stream_TryWrite(struct Stream* stream, UInt8* buffer, UInt32 count); Int32 Stream_TryReadByte(struct Stream* stream); void Stream_SetName(struct Stream* stream, STRING_PURE String* name); -ReturnCode Stream_Skip(struct Stream* stream, UInt32 count); +void Stream_Skip(struct Stream* stream, UInt32 count); void Stream_SetDefaultOps(struct Stream* stream); void Stream_FromFile(struct Stream* stream, void* file, STRING_PURE String* name); @@ -62,27 +62,18 @@ void Stream_ReadonlyBuffered(struct Stream* stream, struct Stream* source, void* UInt8 Stream_ReadU8(struct Stream* stream); -#define Stream_ReadI8(stream) ((Int8)Stream_ReadU8(stream)) UInt16 Stream_ReadU16_LE(struct Stream* stream); -#define Stream_ReadI16_LE(stream) ((Int16)Stream_ReadU16_LE(stream)) UInt16 Stream_ReadU16_BE(struct Stream* stream); -#define Stream_ReadI16_BE(stream) ((Int16)Stream_ReadU16_BE(stream)) UInt32 Stream_ReadU32_LE(struct Stream* stream); -#define Stream_ReadI32_LE(stream) ((Int32)Stream_ReadU32_LE(stream)) UInt32 Stream_ReadU32_BE(struct Stream* stream); +#define Stream_ReadI16_BE(stream) ((Int16)Stream_ReadU16_BE(stream)) #define Stream_ReadI32_BE(stream) ((Int32)Stream_ReadU32_BE(stream)) -UInt64 Stream_ReadU64_BE(struct Stream* stream); -#define Stream_ReadI64_BE(stream) ((Int64)Stream_ReadU64_BE(stream)) void Stream_WriteU8(struct Stream* stream, UInt8 value); -#define Stream_WriteI8(stream, value) Stream_WriteU8(stream, (UInt8)(value)) -void Stream_WriteU16_LE(struct Stream* stream, UInt16 value); -#define Stream_WriteI16_LE(stream, value) Stream_WriteU16_LE(stream, (UInt16)(value)) void Stream_WriteU16_BE(struct Stream* stream, UInt16 value); -#define Stream_WriteI16_BE(stream, value) Stream_WriteU16_BE(stream, (UInt16)(value)) void Stream_WriteU32_LE(struct Stream* stream, UInt32 value); -#define Stream_WriteI32_LE(stream, value) Stream_WriteU32_LE(stream, (UInt32)(value)) void Stream_WriteU32_BE(struct Stream* stream, UInt32 value); +#define Stream_WriteI16_BE(stream, value) Stream_WriteU16_BE(stream, (UInt16)(value)) #define Stream_WriteI32_BE(stream, value) Stream_WriteU32_BE(stream, (UInt32)(value)) /* Reads a UTF8 encoded character from the given stream. Returns false if end of stream. */ diff --git a/src/Client/TexturePack.c b/src/Client/TexturePack.c index 43fd18f6c..461ffdf30 100644 --- a/src/Client/TexturePack.c +++ b/src/Client/TexturePack.c @@ -29,16 +29,16 @@ static String Zip_ReadFixedString(struct Stream* stream, UChar* buffer, UInt16 l static void Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntry* entry) { struct Stream* stream = state->Input; - UInt16 versionNeeded = Stream_ReadU16_LE(stream); - UInt16 flags = Stream_ReadU16_LE(stream); + Stream_ReadU16_LE(stream); /* version needed */ + Stream_ReadU16_LE(stream); /* flags */ UInt16 compressionMethod = Stream_ReadU16_LE(stream); Stream_ReadU32_LE(stream); /* last modified */ Stream_ReadU32_LE(stream); /* CRC32 */ - Int32 compressedSize = Stream_ReadI32_LE(stream); - if (compressedSize == 0) compressedSize = entry->CompressedDataSize; - Int32 uncompressedSize = Stream_ReadI32_LE(stream); - if (uncompressedSize == 0) uncompressedSize = entry->UncompressedDataSize; + UInt32 compressedSize = Stream_ReadU32_LE(stream); + if (compressedSize == 0) compressedSize = entry->CompressedSize; + UInt32 uncompressedSize = Stream_ReadU32_LE(stream); + if (uncompressedSize == 0) uncompressedSize = entry->UncompressedSize; UInt16 fileNameLen = Stream_ReadU16_LE(stream); UInt16 extraFieldLen = Stream_ReadU16_LE(stream); @@ -46,14 +46,9 @@ static void Zip_ReadLocalFileHeader(struct ZipState* state, struct ZipEntry* ent String filename = Zip_ReadFixedString(stream, filenameBuffer, fileNameLen); if (!state->SelectEntry(&filename)) return; - ReturnCode code = Stream_Skip(stream, extraFieldLen); - ErrorHandler_CheckOrFail(code, "Zip - skipping local header extra"); - if (versionNeeded > 20) { - Int32 version = versionNeeded; - Platform_Log1("May not be able to properly extract a .zip enty with version %i", &version); - } - + Stream_Skip(stream, extraFieldLen); struct Stream portion, compStream; + if (compressionMethod == 0) { Stream_ReadonlyPortion(&portion, stream, uncompressedSize); state->ProcessEntry(&filename, &portion, entry); @@ -75,9 +70,9 @@ static void Zip_ReadCentralDirectory(struct ZipState* state, struct ZipEntry* en Stream_ReadU16_LE(stream); /* flags */ Stream_ReadU16_LE(stream); /* compresssion method*/ Stream_ReadU32_LE(stream); /* last modified */ - entry->Crc32 = Stream_ReadU32_LE(stream); - entry->CompressedDataSize = Stream_ReadI32_LE(stream); - entry->UncompressedDataSize = Stream_ReadI32_LE(stream); + entry->Crc32 = Stream_ReadU32_LE(stream); + entry->CompressedSize = Stream_ReadU32_LE(stream); + entry->UncompressedSize = Stream_ReadU32_LE(stream); UInt16 fileNameLen = Stream_ReadU16_LE(stream); UInt16 extraFieldLen = Stream_ReadU16_LE(stream); @@ -85,21 +80,20 @@ static void Zip_ReadCentralDirectory(struct ZipState* state, struct ZipEntry* en Stream_ReadU16_LE(stream); /* disk number */ Stream_ReadU16_LE(stream); /* internal attributes */ Stream_ReadU32_LE(stream); /* external attributes */ - entry->LocalHeaderOffset = Stream_ReadI32_LE(stream); + entry->LocalHeaderOffset = Stream_ReadU32_LE(stream); UInt32 extraDataLen = fileNameLen + extraFieldLen + fileCommentLen; - ReturnCode code = Stream_Skip(stream, extraDataLen); - ErrorHandler_CheckOrFail(code, "Zip - skipping central header extra"); + Stream_Skip(stream, extraDataLen); } -static void Zip_ReadEndOfCentralDirectory(struct ZipState* state, Int32* centralDirectoryOffset) { +static void Zip_ReadEndOfCentralDirectory(struct ZipState* state, UInt32* centralDirectoryOffset) { struct Stream* stream = state->Input; Stream_ReadU16_LE(stream); /* disk number */ Stream_ReadU16_LE(stream); /* disk number start */ Stream_ReadU16_LE(stream); /* disk entries */ state->EntriesCount = Stream_ReadU16_LE(stream); Stream_ReadU32_LE(stream); /* central directory size */ - *centralDirectoryOffset = Stream_ReadI32_LE(stream); + *centralDirectoryOffset = Stream_ReadU32_LE(stream); Stream_ReadU16_LE(stream); /* comment length */ } @@ -135,7 +129,7 @@ ReturnCode Zip_Extract(struct ZipState* state) { } if (sig != ZIP_SIG_ENDOFCENTRALDIR) return ZIP_ERR_NO_END_OF_CENTRAL_DIR; - Int32 centralDirectoryOffset; + UInt32 centralDirectoryOffset; Zip_ReadEndOfCentralDirectory(state, ¢ralDirectoryOffset); result = stream->Seek(stream, centralDirectoryOffset, STREAM_SEEKFROM_BEGIN); if (result != 0) return ZIP_ERR_SEEK_CENTRAL_DIR; diff --git a/src/Client/TexturePack.h b/src/Client/TexturePack.h index 8e4f8f1d4..3c47e2029 100644 --- a/src/Client/TexturePack.h +++ b/src/Client/TexturePack.h @@ -9,7 +9,7 @@ struct Stream; struct Bitmap; struct AsyncRequest; -struct ZipEntry { Int32 CompressedDataSize, UncompressedDataSize, LocalHeaderOffset; UInt32 Crc32; }; +struct ZipEntry { UInt32 CompressedSize, UncompressedSize, LocalHeaderOffset, Crc32; }; #define ZIP_MAX_ENTRIES 2048 struct ZipState {