Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["FilePathsBase", "Test", "Random"]
test = ["FilePathsBase", "Random", "Test"]
5 changes: 4 additions & 1 deletion src/loadsave.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,12 @@ savestreaming

# if a bare filename or IO stream are given, query for the format and dispatch
# to the formatted handlers below
for fn in (:load, :loadstreaming, :save, :savestreaming, :metadata)
for fn in (:load, :loadstreaming, :metadata)
@eval $fn(file, args...; options...) = $fn(query(file), args...; options...)
end
for fn in (:save, :savestreaming)
@eval $fn(file, args...; options...) = $fn(query(file; checkfile=false), args...; options...)
end

# return a save function, so you can do `thing_to_save |> save("filename.ext")`
save(file; options...) = data -> save(file, data; options...)
Expand Down
15 changes: 10 additions & 5 deletions src/query.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,29 @@ end


"""
`query(filename)` returns a `File` object with information about the
query(filename; checkfile=true)

Return a `File` object with information about the
format inferred from the file's extension and/or magic bytes.
If `filename` already exists, the file's magic bytes will take priority
unless `checkfile` is false.
"""
function query(filename)
function query(filename; checkfile::Bool=true)
checkfile &= isfile(filename)
_, ext = splitext(filename)
if haskey(ext2sym, ext)
sym = ext2sym[ext]
no_magic = !hasmagic(sym)
if lensym(sym) == 1 && (no_magic || !isfile(filename)) # we only found one candidate and there is no magic bytes, or no file, trust the extension
if lensym(sym) == 1 && (no_magic || !checkfile) # we only found one candidate and there is no magic bytes, or no file, trust the extension
return File{DataFormat{sym}}(filename)
elseif !isfile(filename) && lensym(sym) > 1
elseif !checkfile && lensym(sym) > 1
return File{DataFormat{sym[1]}}(filename)
end
if no_magic && !hasfunction(sym)
error("Some formats with extension ", ext, " have no magic bytes; use `File{format\"FMT\"}(filename)` to resolve the ambiguity.")
end
end
!isfile(filename) && return File{unknown_df}(filename) # (no extension || no magic byte) && no file
!checkfile && return File{unknown_df}(filename) # (no extension || no magic byte) && no file
# Otherwise, check the magic bytes
file!(query(open(filename), abspath(filename)))
end
Expand Down
13 changes: 13 additions & 0 deletions test/loadsave.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,19 @@ end # module Dummy
@test_throws Exception save("missing.fmt",5)
end

@testset "Overwrite file with bad magic bytes" begin
# issue #267
a = [0x01,0x02,0x03]
fn = tempname()*".dmy"
open(fn, "w") do io
write(io, "Ceci n'est pas un DUMMY")
end
save(fn, a)
@test isa(query(fn), File{format"DUMMY"})
@test load(fn) == a
rm(fn)
end

del_format(format"DUMMY")

# PPM/PBM can be either binary or text. Test that the defaults work,
Expand Down