-
Notifications
You must be signed in to change notification settings - Fork 18k
Slice of runes doesn't trigger "out of bounds" panic #14232
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
Comments
Something even more scary: package main
import (
"fmt"
)
func main() {
s := "ž"
fmt.Println(string([]rune(s)[0:32]))
fmt.Println()
fmt.Printf("%x\n",string([]rune(s)[0:32]))
fmt.Printf("%x\n",string([]rune(s)[0:32]))
fmt.Printf("%x\n",string([]rune(s)[0:32]))
fmt.Printf("%x\n",string([]rune(s)[0:32]))
fmt.Println()
for i := 1; i <10; i++ {
fmt.Printf("%x\n",string([]rune(s)[0:32]))
}
} Prints:
http://play.golang.org/p/rym8a5JpEO The output in the loop is the same for all iterations, but that's not true for individual prints suggesting at least something in the area of the rune leaks. |
Yeah, this is buggy. http://play.golang.org/p/gma2M0wVxO It does do a bounds check if the slice is on a variable instead of a conversion expression: http://play.golang.org/p/KH3KD6MWrw /cc @rsc @griesemer |
And panics for sufficiently large indices: http://play.golang.org/p/xb-ulwT1b0 |
Sorry, yes, I retract this. Agree there is a problem. |
@kardianos see prints that are not in a loop - it's printing seemingly random data beyond the 2 bytes used by the actual rune content - possible out of bounds read. |
http://play.golang.org/p/j9_oAeLzuu different capacity of the rune slice, depending on how it's used later on. |
I believe the only bug here is that the conversion from string to []rune doesn't zero the data between len and cap. |
/cc @dr2chase @randall77 too |
@randall77 should a type conversion like string -> rune really return cap > len? |
Looks like rawruneslice and rawbyteslice do the right thing. The bug is when the compiler passes in a stack-allocated buffer for stringtoslicerune to fill. I'll code up a fix. |
I note that this was also broken in Go 1.5, although 1.4 seems to get it right. |
CL https://golang.org/cl/19231 mentions this issue. |
@ianlancetaylor Yes, if we ever do a 1.5.4 we should include a fix for this. @dominikh It seems ok, even desirable, to return a slice with cap>len. If the backing slice is malloc'd, the unused space between the slice length and the sizeclass size is wasted, might as well let the caller allocate into it. I imagine a ([]byte)("...") followed by an append is reasonably common. Of course, as we see, it is a land of potential bugs... |
I think the fix here was the right one. The cap should match the len, just as []byte{'a', 'b', 'c'} does. This was just a bug. I don't believe there's any need for a Go 1.5.4. |
http://play.golang.org/p/RHdDVEdo7H
I'm not sure if this is bug -- but I'd expect panic on both lines. Why the
string()
-encapsulated slice doesn't trigger the panic?The text was updated successfully, but these errors were encountered: