Skip to content

Commit

Permalink
Avoid double done call in join and add tests
Browse files Browse the repository at this point in the history
Some iterators might mutate their state in the `done()` method (eg Task)
and that will give wrong results when `join` calls `done` twice per
iteration. This fixes that, and add a few tests to `join` that were
missing.

Fixes #9178
  • Loading branch information
ivarne committed Nov 27, 2014
1 parent ee6d56f commit 8bd554c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
12 changes: 8 additions & 4 deletions base/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1394,19 +1394,23 @@ function print_joined(io, strings, delim, last)
end
str, i = next(strings,i)
print(io, str)
while !done(strings,i)
is_done = done(strings,i)
while !is_done
str, i = next(strings,i)
print(io, done(strings,i) ? last : delim)
is_done = done(strings,i)
print(io, is_done ? last : delim)
print(io, str)
end
end

function print_joined(io, strings, delim)
i = start(strings)
while !done(strings,i)
is_done = done(strings,i)
while !is_done
str, i = next(strings,i)
is_done = done(strings,i)
print(io, str)
if !done(strings,i)
if !is_done
print(io, delim)
end
end
Expand Down
17 changes: 17 additions & 0 deletions test/strings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1249,3 +1249,20 @@ end
# This caused JuliaLang/JSON.jl#82
@test first('\x00':'\x7f') === '\x00'
@test last('\x00':'\x7f') === '\x7f'

# Tests of join()
@test join([]) == ""
@test join(["a"],"?") == "a"
@test join("HELLO",'-') == "H-E-L-L-O"
@test join(1:5, ", ", " and ") == "1, 2, 3, 4 and 5"
@test join(["apples", "bananas", "pineapples"], ", ", " and ") == "apples, bananas and pineapples"

# issue #9178 `join` calls `done()` twice on the iterables
type i9178
nnext::Int64
ndone::Int64
end
Base.start(jt::i9178) = (jt.nnext=0 ; jt.ndone=0 ; 0)
Base.done(jt::i9178, n) = (jt.ndone += 1 ; n > 3)
Base.next(jt::i9178, n) = (jt.nnext += 1 ; ("$(jt.nnext),$(jt.ndone)", n+1))
@test join(i9178(0,0), ";") == "1,1;2,2;3,3;4,4"

0 comments on commit 8bd554c

Please sign in to comment.