From d0ba754dc2c9b4346be78f1f261d8b09d5012bb3 Mon Sep 17 00:00:00 2001 From: 5ec1cff <56485584+5ec1cff@users.noreply.github.com> Date: Sat, 22 Mar 2025 20:54:26 +0800 Subject: [PATCH] patterns/zip: Handling padded extra fields (#369) * Handling unresolved extra fields * Update zip.hexpat * Update zip.hexpat * Update zip.hexpat --- patterns/zip.hexpat | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/patterns/zip.hexpat b/patterns/zip.hexpat index 492e7ad..1d69a7b 100644 --- a/patterns/zip.hexpat +++ b/patterns/zip.hexpat @@ -75,19 +75,26 @@ namespace extra { struct ExtraField { u16 tag; u16 TSize; - if (tag == 0x5455){ + if (tag == 0x5455) { extra::X5455_ExtendedTimestamp x5455_ExtendedTimestamp; - }else if (tag == 0x000a){ + } else if (tag == 0x000a) { extra::X000A_NTFS x000A_NTFS; - }else if (tag == 0x7875){ + } else if (tag == 0x7875) { extra::X7875_NewUnix x7875_NewUnix; - }else if (tag == 0x5855){ + } else if (tag == 0x5855) { extra::X5855_InfoZipUnix x5855_InfoZipUnix; - }else{ + } else { std::print("Unsupported tag 0x{:02X}", tag); padding[TSize]; } }; + + fn has_extra_field(u32 extraEnd) { + if ($ + 4 > extraEnd) return false; + u16 tag = std::mem::read_unsigned($, 2, std::mem::Endian::Little); + u16 len = std::mem::read_unsigned($ + 2, 2, std::mem::Endian::Little); + return !(tag == 0 || len == 0) && $ + 4 + len <= extraEnd; + }; } fn find_eocd() { @@ -184,7 +191,8 @@ struct LocalFileHeader { u16 extraFieldLength [[ comment("Extra field length (m)") ]]; char fileName[fileNameLength] [[ comment("File Name") ]]; u64 extraEnd = $ + extraFieldLength; - extra::ExtraField extraFields[while ($ < extraEnd)] [[comment("Extra Fields")]]; + extra::ExtraField extraFields[while (extra::has_extra_field(extraEnd))] [[comment("Extra Fields")]]; + padding[extraEnd - $]; u8 data[compressedSize] [[name("File Data")]]; }; @@ -213,8 +221,9 @@ struct CentralDirectoryFileHeader { File file; char fileName[fileNameLength]; u64 extraEnd = $ + extraFieldLength; - extra::ExtraField extraFields[while ($ < extraEnd)] [[comment("Extra Fields")]]; - char comment[fileCommentLength]; + extra::ExtraField extraFields[while (extra::has_extra_field(extraEnd))] [[comment("Extra Fields")]]; + padding[extraEnd - $]; + char comment[fileCommentLength] @ extraEnd; }; -CentralDirectoryFileHeader centralDirHeaders[fileInfo.CDRCount] @ (fileInfo.CDOffset) [[name("Files")]]; \ No newline at end of file +CentralDirectoryFileHeader centralDirHeaders[fileInfo.CDRCount] @ (fileInfo.CDOffset) [[name("Files")]];