draw: fix crash caused by Scale by Copy shortcut
When DstMask is not nil, this shortcut causes stack overflow because Copy function in turn will call Scale with same dr and sr. Fixes golang/go#23107 Change-Id: I8ccadbd9b7f16363ac17b6114308527d6fa9456e Reviewed-on: https://go-review.googlesource.com/83537 Reviewed-by: Nigel Tao <nigeltao@golang.org> Run-TryBot: Nigel Tao <nigeltao@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
e5db4c4663
commit
12117c17ca
|
@ -877,8 +877,9 @@ func relName(s string) string {
|
||||||
const (
|
const (
|
||||||
codeRoot = `
|
codeRoot = `
|
||||||
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||||
// Try to simplify a Scale to a Copy.
|
// Try to simplify a Scale to a Copy when DstMask is not specified.
|
||||||
if dr.Size() == sr.Size() {
|
// If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
|
||||||
|
if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
|
||||||
Copy(dst, dr.Min, src, sr, op, opts)
|
Copy(dst, dr.Min, src, sr, op, opts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
10
draw/impl.go
10
draw/impl.go
|
@ -11,8 +11,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||||
// Try to simplify a Scale to a Copy.
|
// Try to simplify a Scale to a Copy when DstMask is not specified.
|
||||||
if dr.Size() == sr.Size() {
|
// If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
|
||||||
|
if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
|
||||||
Copy(dst, dr.Min, src, sr, op, opts)
|
Copy(dst, dr.Min, src, sr, op, opts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1048,8 +1049,9 @@ func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectang
|
||||||
}
|
}
|
||||||
|
|
||||||
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
|
||||||
// Try to simplify a Scale to a Copy.
|
// Try to simplify a Scale to a Copy when DstMask is not specified.
|
||||||
if dr.Size() == sr.Size() {
|
// If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
|
||||||
|
if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
|
||||||
Copy(dst, dr.Min, src, sr, op, opts)
|
Copy(dst, dr.Min, src, sr, op, opts)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,6 +551,17 @@ func TestRectDstMask(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDstMaskSameSizeCopy(t *testing.T) {
|
||||||
|
bounds := image.Rect(0, 0, 42, 42)
|
||||||
|
src := image.Opaque
|
||||||
|
dst := image.NewRGBA(bounds)
|
||||||
|
mask := image.NewRGBA(bounds)
|
||||||
|
|
||||||
|
Copy(dst, image.ZP, src, bounds, Src, &Options{
|
||||||
|
DstMask: mask,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: delete this wrapper type once Go 1.5 is released, where an
|
// TODO: delete this wrapper type once Go 1.5 is released, where an
|
||||||
// image.Rectangle implements image.Image.
|
// image.Rectangle implements image.Image.
|
||||||
type rectImage image.Rectangle
|
type rectImage image.Rectangle
|
||||||
|
|
Loading…
Reference in New Issue
Block a user