@@ -2,7 +2,16 @@ import { FileParserError } from '@/lib/file-parsers/errors'
22import { isEncryptedOoxmlContainer } from '@/lib/file-parsers/ooxml-encryption'
33import type { FileParseOptions } from '@/lib/file-parsers/types'
44import { decodeTextBuffer , detectBomlessUtf16 } from '@/lib/file-parsers/utils'
5- import { isZipShaped } from '@/lib/file-parsers/zip-guard'
5+ import {
6+ CENTRAL_DIRECTORY_HEADER_MIN_SIZE ,
7+ CENTRAL_DIRECTORY_HEADER_SIGNATURE ,
8+ COMPRESSION_METHOD_STORED ,
9+ EOCD_MIN_SIZE ,
10+ findEocdOffset ,
11+ isZipShaped ,
12+ LOCAL_FILE_HEADER_MIN_SIZE ,
13+ locateCentralDirectory ,
14+ } from '@/lib/file-parsers/zip-guard'
615
716/**
817 * What the bytes of a buffer look like, independent of the caller-supplied
@@ -34,18 +43,6 @@ const OLE2_SIGNATURE = Buffer.from([0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0x
3443/** An RTF file is a group opening with the `rtf` control word; nothing may precede it. */
3544const RTF_SIGNATURE = Buffer . from ( '{\\rtf' , 'latin1' )
3645
37- const EOCD_SIGNATURE = 0x06054b50
38- const EOCD_MIN_SIZE = 22
39- const MAX_EOCD_COMMENT_SIZE = 0xffff
40- const ZIP64_EOCD_LOCATOR_SIGNATURE = 0x07064b50
41- const ZIP64_EOCD_LOCATOR_SIZE = 20
42- const ZIP64_EOCD_SIGNATURE = 0x06064b50
43- const CENTRAL_DIRECTORY_HEADER_SIGNATURE = 0x02014b50
44- const CENTRAL_DIRECTORY_HEADER_MIN_SIZE = 46
45- const LOCAL_FILE_HEADER_MIN_SIZE = 30
46- const COMPRESSION_METHOD_STORED = 0
47- const UINT16_SENTINEL = 0xffff
48- const UINT32_SENTINEL = 0xffffffff
4946/** Enough to reach the first `word/`, `xl/` or `ppt/` part in any real package. */
5047const MAX_INSPECTED_ENTRIES = 256
5148const MAX_MIMETYPE_BYTES = 128
@@ -63,37 +60,6 @@ interface ZipEntry {
6360 localHeaderOffset : number
6461}
6562
66- /** Same EOCD anchoring as the zip guard: only a record whose comment ends the buffer counts. */
67- function findEocdOffset ( buffer : Buffer ) : number {
68- const minStart = Math . max ( 0 , buffer . length - EOCD_MIN_SIZE - MAX_EOCD_COMMENT_SIZE )
69- for ( let offset = buffer . length - EOCD_MIN_SIZE ; offset >= minStart ; offset -- ) {
70- if ( buffer . readUInt32LE ( offset ) !== EOCD_SIGNATURE ) continue
71- const commentLength = buffer . readUInt16LE ( offset + 20 )
72- if ( offset + EOCD_MIN_SIZE + commentLength === buffer . length ) return offset
73- }
74- return - 1
75- }
76-
77- function locateCentralDirectory ( buffer : Buffer , eocdOffset : number ) : number | null {
78- const entryCount = buffer . readUInt16LE ( eocdOffset + 10 )
79- const directoryOffset = buffer . readUInt32LE ( eocdOffset + 16 )
80- if ( entryCount !== UINT16_SENTINEL && directoryOffset !== UINT32_SENTINEL ) {
81- return directoryOffset
82- }
83-
84- const locatorOffset = eocdOffset - ZIP64_EOCD_LOCATOR_SIZE
85- if ( locatorOffset < 0 || buffer . readUInt32LE ( locatorOffset ) !== ZIP64_EOCD_LOCATOR_SIGNATURE ) {
86- return null
87- }
88- const zip64Eocd = buffer . readBigUInt64LE ( locatorOffset + 8 )
89- if ( zip64Eocd > BigInt ( buffer . length - 56 ) ) return null
90- const zip64EocdOffset = Number ( zip64Eocd )
91- if ( buffer . readUInt32LE ( zip64EocdOffset ) !== ZIP64_EOCD_SIGNATURE ) return null
92- const zip64DirectoryOffset = buffer . readBigUInt64LE ( zip64EocdOffset + 48 )
93- if ( zip64DirectoryOffset > BigInt ( buffer . length ) ) return null
94- return Number ( zip64DirectoryOffset )
95- }
96-
9763/**
9864 * Reads central-directory entry names without decompressing anything. Returns
9965 * `null` for a buffer whose directory cannot be located. Bounded to the first
@@ -104,8 +70,8 @@ function readZipEntries(buffer: Buffer): ZipEntry[] | null {
10470 if ( buffer . length < EOCD_MIN_SIZE ) return null
10571 const eocdOffset = findEocdOffset ( buffer )
10672 if ( eocdOffset < 0 ) return null
107- const directoryOffset = locateCentralDirectory ( buffer , eocdOffset )
108- if ( directoryOffset === null ) return null
73+ const directoryOffset = locateCentralDirectory ( buffer , eocdOffset ) ?. offset
74+ if ( directoryOffset === undefined ) return null
10975
11076 const entries : ZipEntry [ ] = [ ]
11177 let cursor = directoryOffset
0 commit comments