Description
Hi,
we found a bug during unmarshaling large responses from HTTP.Request.Body. The next conditions should be met:
- Iterator reads data from
io.Reader
, - expected value is
0
(zero) Iterator.tail == Iterator.head + 1
Iterator.tail < len(Iterator.buf)
- value in the buffer after
Iterator.tail
is presented from the previous read and has '.' character.
Basically, let's assume that Iterator
reads data from the reader which returns less data, than the size of the buffer. After a couple of reads, the buffer will have the content like: 0.0, 0.0, 0
.
The first item is from the latest read, other items are from the older readers, so have:
buf: []bytes(`0.0, 0.0, 0`)
head: 0 // ---^
tail: 1 // ----^
When the Iterator.ReadInt
is called, it reads zero and checks if the value is an integer by calling assertInteger()
method, which currently looks like:
func (iter *Iterator) assertInteger() {
if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
iter.ReportError("assertInteger", "can not decode float as int")
}
}
The only issue is, that it checks for iter.head < len(iter.buf)
instead of iter.head < iter.tail
and the assertion is done against the dot .
from the previous read.
The test for replicating this behavior will be provided in ongoing PR.