Skip to content

Commit 6da0f9d

Browse files
committed
Improve reader robustness + tests for bad ply headers
1 parent f264ba1 commit 6da0f9d

File tree

2 files changed

+88
-29
lines changed

2 files changed

+88
-29
lines changed

src/io.jl

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -68,43 +68,54 @@ function read_header(ply_file)
6868
format = nothing
6969
while true
7070
line = Compat.readline(ply_file)
71-
if line == "end_header"
71+
if line == "" && eof(ply_file)
72+
throw(ErrorException("Unexpected end of file reading ply header"))
73+
elseif line == "end_header"
7274
break
7375
elseif startswith(line, "comment")
7476
push!(comments, PlyComment(strip(line[8:end]), length(elements)+1))
75-
elseif startswith(line, "format")
76-
tok, format_type, format_version = split(line)
77-
@assert tok == "format"
78-
if format_version != "1.0"
79-
throw(ErrorException("Expected ply version 1.0, got $format_version"))
80-
end
81-
format = format_type == "ascii" ? Format_ascii :
82-
format_type == "binary_little_endian" ? Format_binary_little :
83-
format_type == "binary_big_endian" ? Format_binary_big :
84-
error("Unknown ply format $format_type")
85-
elseif startswith(line, "element")
86-
if !isempty(element_name)
87-
push!(elements, PlyElement(element_name, element_numel, element_props))
88-
element_props = Vector{AbstractVector}()
89-
end
90-
tok, element_name, element_numel = split(line)
91-
@assert tok == "element"
92-
element_numel = parse(Int,element_numel)
93-
elseif startswith(line, "property")
77+
else
9478
tokens = split(line)
95-
@assert tokens[1] == "property"
96-
if tokens[2] == "list"
97-
count_type_name, type_name, prop_name = tokens[3:end]
98-
count_type = ply_type(count_type_name)
99-
type_ = ply_type(type_name)
100-
push!(element_props, ListProperty(prop_name, ply_type(count_type_name), ply_type(type_name)))
79+
length(tokens) > 2 || throw(ErrorException("Bad ply header, line: \"$line\""))
80+
if tokens[1] == "format"
81+
length(tokens) == 3 || throw(ErrorException("Bad ply header, line: \"$line\""))
82+
_, format_type, format_version = tokens
83+
if format_version != "1.0"
84+
throw(ErrorException("Expected ply version 1.0, got $format_version"))
85+
end
86+
format = format_type == "ascii" ? Format_ascii :
87+
format_type == "binary_little_endian" ? Format_binary_little :
88+
format_type == "binary_big_endian" ? Format_binary_big :
89+
error("Unknown ply format $format_type")
90+
elseif tokens[1] == "element"
91+
if !isempty(element_name)
92+
push!(elements, PlyElement(element_name, element_numel, element_props))
93+
element_props = Vector{AbstractVector}()
94+
end
95+
length(tokens) == 3 || throw(ErrorException("Bad ply header, line: \"$line\""))
96+
_, element_name, element_numel = tokens
97+
element_numel = parse(Int,element_numel)
98+
elseif tokens[1] == "property"
99+
!isempty(element_name) || throw(ErrorException("Bad ply header: property before first element"))
100+
if tokens[2] == "list"
101+
length(tokens) == 5 || throw(ErrorException("Bad ply header, line: \"$line\""))
102+
count_type_name, type_name, prop_name = tokens[3:end]
103+
count_type = ply_type(count_type_name)
104+
type_ = ply_type(type_name)
105+
push!(element_props, ListProperty(prop_name, ply_type(count_type_name), ply_type(type_name)))
106+
else
107+
length(tokens) == 3 || throw(ErrorException("Bad ply header, line: \"$line\""))
108+
type_name, prop_name = tokens[2:end]
109+
push!(element_props, ArrayProperty(prop_name, ply_type(type_name)))
110+
end
101111
else
102-
type_name, prop_name = tokens[2:end]
103-
push!(element_props, ArrayProperty(prop_name, ply_type(type_name)))
112+
throw(ErrorException("Bad ply header, line: \"$line\""))
104113
end
105114
end
106115
end
107-
push!(elements, PlyElement(element_name, element_numel, element_props))
116+
if !isempty(element_name)
117+
push!(elements, PlyElement(element_name, element_numel, element_props))
118+
end
108119
elements, format, comments
109120
end
110121

test/runtests.jl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,52 @@ end
165165
end
166166

167167

168+
@testset "Malformed ply headers" begin
169+
@test_throws ErrorException load_ply(IOBuffer("asdf"))
170+
171+
@test_throws ErrorException load_ply(IOBuffer("ply"))
172+
173+
@test_throws ErrorException load_ply(IOBuffer("""
174+
ply
175+
format ascii 2.0
176+
"""))
177+
178+
@test_throws ErrorException load_ply(IOBuffer("""
179+
ply
180+
format 1.0
181+
end_header"""))
182+
183+
@test_throws ErrorException load_ply(IOBuffer("""
184+
ply
185+
format ascii 1.0
186+
asdf
187+
end_header"""))
188+
189+
@test_throws ErrorException load_ply(IOBuffer("""
190+
ply
191+
format ascii 1.0
192+
element el
193+
end_header"""))
194+
195+
@test_throws ErrorException load_ply(IOBuffer("""
196+
ply
197+
format ascii 1.0
198+
property float x
199+
end_header"""))
200+
201+
@test_throws ErrorException load_ply(IOBuffer("""
202+
ply
203+
format ascii 1.0
204+
element el 0
205+
property
206+
end_header"""))
207+
208+
@test_throws ErrorException load_ply(IOBuffer("""
209+
ply
210+
format ascii 1.0
211+
element el 0
212+
property list
213+
end_header"""))
214+
end
215+
168216
end # @testset PlyIO

0 commit comments

Comments
 (0)