image/jpeg: return io.ErrUnexpectedEOF on truncated data

Decoder calls fill from readFull, ignore and readByte and
readByte did not check returned io.EOF.

This change moves io.EOF translation inside fill.

name                 old speed      new speed      delta
DecodeBaseline-8     67.4MB/s ± 0%  67.3MB/s ± 0%  -0.20%  (p=0.000 n=16+19)
DecodeProgressive-8  43.7MB/s ± 0%  43.6MB/s ± 0%  -0.06%  (p=0.013 n=17+19)

Fixes #56724

Change-Id: Ia0d5cc561f3c2050e25ec3f2b5e6866c3b4941c7
GitHub-Last-Rev: 470154373bc1452dffc5293d9a840e972749a76d
GitHub-Pull-Request: golang/go#56863
Reviewed-on: https://go-review.googlesource.com/c/go/+/452335
Run-TryBot: Rob Pike <r@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
Reviewed-by: Nigel Tao (INACTIVE; USE @golang.org INSTEAD) <nigeltao@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Alexander Yastrebov 2023-02-04 14:52:55 +00:00 committed by Nigel Tao
parent 52fea4b3d9
commit f684f3dc43
3 changed files with 19 additions and 8 deletions

View File

@ -49,7 +49,7 @@ func (d *decoder) ensureNBits(n int32) error {
for {
c, err := d.readByteStuffedByte()
if err != nil {
if err == io.EOF {
if err == io.ErrUnexpectedEOF {
return errShortHuffmanData
}
return err

View File

@ -164,7 +164,10 @@ func (d *decoder) fill() error {
n, err := d.r.Read(d.bytes.buf[d.bytes.j:])
d.bytes.j += n
if n > 0 {
err = nil
return nil
}
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
return err
}
@ -261,9 +264,6 @@ func (d *decoder) readFull(p []byte) error {
break
}
if err := d.fill(); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
return err
}
}
@ -291,9 +291,6 @@ func (d *decoder) ignore(n int) error {
break
}
if err := d.fill(); err != nil {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
return err
}
}

View File

@ -490,6 +490,20 @@ func TestExtraneousData(t *testing.T) {
}
}
func TestIssue56724(t *testing.T) {
b, err := os.ReadFile("../testdata/video-001.jpeg")
if err != nil {
t.Fatal(err)
}
b = b[:24] // truncate image data
_, err = Decode(bytes.NewReader(b))
if err != io.ErrUnexpectedEOF {
t.Errorf("got: %v, want: %v", err, io.ErrUnexpectedEOF)
}
}
func benchmarkDecode(b *testing.B, filename string) {
data, err := os.ReadFile(filename)
if err != nil {