Skip to content

Commit 1dedb46

Browse files
authored
Port new go test and change EOCD search to match yauzl (#83)
* add new go test file * Use yauzl eocd search method
1 parent 4f080a9 commit 1dedb46

File tree

4 files changed

+16
-23
lines changed

4 files changed

+16
-23
lines changed

src/reader.jl

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -345,40 +345,32 @@ end
345345

346346
# If this fails, io isn't a zip file, io isn't seekable,
347347
# or the end of the zip file was corrupted
348+
# Using yauzl method https://github.com/thejoshwolfe/yauzl/blob/51010ce4e8c7e6345efe195e1b4150518f37b393/index.js#L111-L113
348349
function find_end_of_central_directory_record(io::IO)::Int64
349350
seekend(io)
350351
fsize = position(io)
351-
# First assume comment is length zero
352352
fsize 22 || throw(ArgumentError("io isn't a zip file. Too small"))
353-
seek(io, fsize-22)
354-
b = read!(io, zeros(UInt8, 22))
355-
check_comment_len_valid(b, comment_len) = (
356-
EOCDSig == @view(b[end-21-comment_len:end-18-comment_len]) &&
357-
comment_len%UInt8 == b[end-1-comment_len] &&
358-
UInt8(comment_len>>8) == b[end-comment_len]
359-
)
360-
if check_comment_len_valid(b, 0)
361-
# No Zip comment fast path
362-
fsize-22
363-
else
364-
# There maybe is a Zip comment slow path
365-
fsize > 22 || throw(ArgumentError("io isn't a zip file."))
366-
max_comment_len::Int = min(0xFFFF, fsize-22)
367-
seek(io, fsize - (max_comment_len+22))
368-
b = read!(io, zeros(UInt8, (max_comment_len+22)))
369-
comment_len = 1
370-
while comment_len < max_comment_len && !check_comment_len_valid(b, comment_len)
371-
comment_len += 1
353+
for comment_len in 0:Int(min(0xFFFF, fsize-22))
354+
seek(io, fsize-22-comment_len)
355+
if readle(io, UInt32) != 0x06054b50
356+
continue
372357
end
373-
if !check_comment_len_valid(b, comment_len)
358+
skip(io, 16)
359+
if readle(io, UInt16) == comment_len
360+
return fsize-22-comment_len
361+
else
374362
throw(ArgumentError("""
375363
io isn't a zip file.
376364
It may be a zip file with a corrupted ending.
377365
"""
378366
))
379367
end
380-
fsize-22-comment_len
381368
end
369+
throw(ArgumentError("""
370+
io isn't a zip file.
371+
It may be a zip file with a corrupted ending.
372+
"""
373+
))
382374
end
383375

384376
function check_EOCD64_used(io::IO, eocd_offset)::Bool
216 Bytes
Binary file not shown.

test/test_ported-go-tests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ end
3030
"readme.notzip",
3131
"test-baddirsz.zip",
3232
"test-badbase.zip",
33+
"comment-truncated.zip",
3334
]
3435

3536
for filename in same_content_files

test/test_reader.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ using SHA: sha256
6666
@test_throws ArgumentError find_eocd(io)
6767

6868
io = IOBuffer("PK\x05\x06"^30000*"ab")
69-
@test find_eocd(io) == 100700
69+
@test_throws ArgumentError find_eocd(io)
7070

7171
io = IOBuffer("PK\x05\x06"*"\0"^16*"\xff\xff"*"a"^(2^16-1))
7272
@test find_eocd(io) == 0

0 commit comments

Comments
 (0)