Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

image/png: Integer underflow bug on 32-bit systems #12687

yalue opened this issue Sep 19, 2015 · 1 comment

image/png: Integer underflow bug on 32-bit systems #12687

yalue opened this issue Sep 19, 2015 · 1 comment


Copy link

@yalue yalue commented Sep 19, 2015

I noticed this bug in Go 1.5.1 (and earlier versions) on windows/386, but it doesn't affect 64-bit versions (at least not versions that use a 64-bit int type).

The reason for this can be found on line 733 of image/png/reader.go, where min(len(ignored), int(length)) is calculated. length is a 32-bit unsigned value and already guaranteed to be greater than 0. On 64-bit systems, a value of length greater than 0x80000000 will be converted to a valid int because an int value is larger than 32 bits. After the conversion, the value will be safely ignored in favor of len(ignored), which is 4096. On 32-bit systems, however, this value will pass the initial positivity check, but will then become negative when converted to a 32-bit int. This negative value will be seen as the smaller of the two values by min, leading it to be used as an array bound and therefore the panic.

The code shown below attempts to decode a clearly invalid PNG image, but panics instead of returning an error on 32-bit systems:

package main

import (

func main() {
    data := []byte{0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0xff, 0xff,
        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0xf4, 0x7c, 0x55, 0x04, 0x1a,
        0xd3, 0x11, 0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e, 0x00, 0x00,
        0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf4, 0x7c, 0x55, 0x04, 0x1a,
    _, e := png.Decode(bytes.NewReader(data))
    if e != nil {
        fmt.Printf("Got error: %s\n", e)
    } else {
        fmt.Printf("That should have been an error!\n")
@bradfitz bradfitz added this to the Go1.6 milestone Sep 19, 2015
Copy link

@gopherbot gopherbot commented Sep 19, 2015

CL mentions this issue.


@nigeltao nigeltao closed this in 66c25fa Sep 21, 2015
@golang golang locked and limited conversation to collaborators Sep 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants