Skip to content

Commit af40e8a

Browse files
authored
check eof before read bytes (#346)
1 parent 01b504d commit af40e8a

File tree

4 files changed

+51
-10
lines changed

4 files changed

+51
-10
lines changed

Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ julia = "0.7, 1"
1313

1414
[extras]
1515
CSVFiles = "5d742f6a-9f54-50ce-8119-2520741973ca"
16+
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
1617
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
1718
FilePathsBase = "48062228-2e41-5def-b9a4-89aafe57970f"
1819
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
1920
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
2021
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2122

2223
[targets]
23-
test = ["ColorTypes", "CSVFiles", "FilePathsBase", "HTTP", "Random", "Test"]
24+
test = ["ColorTypes", "CodecZlib", "CSVFiles", "FilePathsBase", "HTTP", "Random", "Test"]

src/registry.jl

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,44 @@ detect_compressed(io, len=getlength(io); kwargs...) = detect_compressor(io, len;
5959
# test for RD?n magic sequence at the beginning of R data input stream
6060
function detect_rdata(io)
6161
seekstart(io)
62-
getlength(io) <= 4 && return false
63-
b = read(io, UInt8)
64-
if b == UInt8('R')
65-
return read(io, UInt8) == UInt8('D') &&
66-
read(io, UInt8) in (UInt8('A'), UInt8('B'), UInt8('X')) &&
67-
read(io, UInt8) in (UInt8('2'), UInt8('3')) &&
68-
(c = read(io, UInt8); c == UInt8('\n') || (c == UInt8('\r') && read(io, UInt8) == UInt8('\n')))
62+
function checked_match(io)
63+
for m in (
64+
(UInt8('R'), ),
65+
(UInt8('D'), ),
66+
(UInt8('A'), UInt8('B'), UInt8('X')),
67+
(UInt8('2'), UInt8('3')))
68+
eof(io) && return false
69+
read(io, UInt8) in m || return false
70+
end
71+
c = read(io, UInt8)
72+
if c == UInt8('\r')
73+
eof(io) && return false
74+
c = read(io, UInt8)
75+
end
76+
c == UInt8('\n') || return false
77+
return true
6978
end
79+
checked_match(io) && return true
7080
return detect_compressed(io; formats=["GZIP", "BZIP2", "XZ"])
7181
end
7282

7383
add_format(format"RData", detect_rdata, [".rda", ".RData", ".rdata"], [idRData, LOAD])
7484

7585
function detect_rdata_single(io)
7686
seekstart(io)
77-
res = read(io, UInt8) in (UInt8('A'), UInt8('B'), UInt8('X')) &&
78-
(c = read(io, UInt8); c == UInt8('\n') || (c == UInt8('\r') && read(io, UInt8) == UInt8('\n')))
87+
function checked_match(io)
88+
eof(io) && return false
89+
read(io, UInt8) in (UInt8('A'), UInt8('B'), UInt8('X')) || return false
90+
c = read(io, UInt8)
91+
if c == UInt8('\r')
92+
eof(io) && return false
93+
c = read(io, UInt8)
94+
end
95+
c == UInt8('\n') || return false
96+
return true
97+
end
98+
99+
res = checked_match(io)
79100
if !res
80101
res = detect_compressed(io; formats=["GZIP", "BZIP2", "XZ"])
81102
end

test/query.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,4 +518,22 @@ let file_dir = joinpath(@__DIR__, "files"), file_path = Path(file_dir)
518518
@test FileIO.formatname(q) == :PNG
519519
rm("test.png")
520520
end
521+
522+
@testset "issue #345" begin
523+
iris = joinpath("files", "iris.rda")
524+
525+
q = query(iris)
526+
@test typeof(q) <: File{format"RData"}
527+
528+
io = open(iris)
529+
q = query(io)
530+
@test typeof(q) <: Stream{format"GZIP"} # FIXME: should be RData
531+
@test FileIO.detect_rdata(io)
532+
533+
# issue #345: it errors here
534+
io = CodecZlib.GzipDecompressorStream(open(iris))
535+
q = query(io)
536+
@test FileIO.unknown(q) # FIXME: should be RData
537+
@test FileIO.detect_rdata(io)
538+
end
521539
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ using FileIO
22
using FilePathsBase
33
using Test
44
using UUIDs
5+
using CodecZlib
56

67
Threads.nthreads() <= 1 && @info "Threads.nthreads() = $(Threads.nthreads()), multithread tests will be disabled"
78

0 commit comments

Comments
 (0)