Skip to content

Commit 01bb90e

Browse files
committed
fix
1 parent 8ac96e2 commit 01bb90e

2 files changed

Lines changed: 71 additions & 4 deletions

File tree

src/OpenAPI.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import Base: getindex, keys, length, iterate, hasproperty
88
import JSON: lower
99

1010

11-
const _JSON_PARSE_ALLOW_TRAILING = try; JSON.parse("1 "; allowtrailing=true); true; catch; false; end
11+
const _JSON_PARSE_ISROOT_SUPPORTED = try; JSON.parse("1 "; isroot=false); true; catch; false; end
1212

13-
if _JSON_PARSE_ALLOW_TRAILING
14-
_json_parse(io_or_str) = JSON.parse(io_or_str; allowtrailing=true)
13+
if _JSON_PARSE_ISROOT_SUPPORTED
14+
_json_parse(io_or_str) = JSON.parse(io_or_str; isroot=false)
1515
else
1616
_json_parse(io_or_str) = JSON.parse(io_or_str)
1717
end

src/client/chunk_readers.jl

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,71 @@ struct JSONChunkReader <: AbstractChunkReader
2020
buffered_input::Base.BufferStream
2121
end
2222

23+
function _read_json_chunk(io::IO)
24+
out = IOBuffer()
25+
first_byte = peek(io, UInt8)
26+
27+
if first_byte == UInt8('{') || first_byte == UInt8('[')
28+
close_byte = first_byte == UInt8('{') ? UInt8('}') : UInt8(']')
29+
depth = 0
30+
in_string = false
31+
escaped = false
32+
33+
while !eof(io)
34+
byte = read(io, UInt8)
35+
write(out, byte)
36+
37+
if escaped
38+
escaped = false
39+
continue
40+
end
41+
42+
if in_string
43+
if byte == UInt8('\\')
44+
escaped = true
45+
elseif byte == UInt8('"')
46+
in_string = false
47+
end
48+
else
49+
if byte == UInt8('"')
50+
in_string = true
51+
elseif byte == first_byte
52+
depth += 1
53+
elseif byte == close_byte
54+
depth -= 1
55+
depth == 0 && break
56+
end
57+
end
58+
end
59+
elseif first_byte == UInt8('"')
60+
escaped = false
61+
read(io, UInt8) # consume opening quote
62+
write(out, UInt8('"'))
63+
while !eof(io)
64+
byte = read(io, UInt8)
65+
write(out, byte)
66+
if escaped
67+
escaped = false
68+
elseif byte == UInt8('\\')
69+
escaped = true
70+
elseif byte == UInt8('"')
71+
break
72+
end
73+
end
74+
else
75+
# number / true / false / null: read until delimiter
76+
while !eof(io)
77+
byte = peek(io, UInt8)
78+
if isspace(Char(byte)) || byte == UInt8(',') || byte == UInt8(']') || byte == UInt8('}')
79+
break
80+
end
81+
write(out, read(io, UInt8))
82+
end
83+
end
84+
85+
take!(out)
86+
end
87+
2388
function Base.iterate(iter::JSONChunkReader, _state=nothing)
2489
if eof(iter.buffered_input)
2590
return nothing
@@ -34,7 +99,9 @@ function Base.iterate(iter::JSONChunkReader, _state=nothing)
3499
end
35100
end
36101
eof(iter.buffered_input) && return nothing
37-
valid_json = _json_parse(iter.buffered_input)
102+
chunk_bytes = _read_json_chunk(iter.buffered_input)
103+
isempty(chunk_bytes) && return nothing
104+
valid_json = _json_parse(String(chunk_bytes))
38105
bytes = convert(Vector{UInt8}, codeunits(JSON.json(valid_json)))
39106
return (bytes, iter)
40107
end

0 commit comments

Comments
 (0)