graphics: Limit image size strictly

This commit is contained in:
Hajime Hoshi 2016-11-05 03:06:18 +09:00
parent bb9e69c924
commit e47c3bbbfb
3 changed files with 108 additions and 1 deletions

View File

@ -419,3 +419,80 @@ func TestImageFill(t *testing.T) {
} }
} }
} }
func TestImageSize(t *testing.T) {
sizes := []struct {
width int
height int
error bool
}{
{
width: -1,
height: -1,
error: true,
},
{
width: -1,
height: 1,
error: true,
},
{
width: 1,
height: -1,
error: true,
},
{
width: 0,
height: 0,
error: true,
},
{
width: 0,
height: 1,
error: true,
},
{
width: 1,
height: 0,
error: true,
},
{
width: 1,
height: 1,
error: false,
},
{
width: 4096,
height: 4096,
error: false,
},
{
width: 4096,
height: 4097,
error: true,
},
{
width: 4097,
height: 4096,
error: true,
},
{
width: 4097,
height: 4097,
error: true,
},
}
for _, size := range sizes {
_, err := NewImage(size.width, size.height, FilterNearest)
if err == nil {
if size.error {
t.Errorf("NewImage(%d, %d, ...) must cause error but not", size.width, size.height)
}
return
} else {
if !size.error {
t.Errorf("NewImage(%d, %d, ...) must not cause error but did: %s", size.width, size.height, err)
}
}
}
}

View File

@ -23,6 +23,7 @@ import (
"runtime" "runtime"
"sync" "sync"
"github.com/hajimehoshi/ebiten/internal/graphics"
"github.com/hajimehoshi/ebiten/internal/opengl" "github.com/hajimehoshi/ebiten/internal/opengl"
"github.com/hajimehoshi/ebiten/internal/restorable" "github.com/hajimehoshi/ebiten/internal/restorable"
) )
@ -32,7 +33,27 @@ type imageImpl struct {
m sync.Mutex m sync.Mutex
} }
func checkSize(width, height int) error {
if width <= 0 {
return fmt.Errorf("ebiten: width must be more than 0")
}
if height <= 0 {
return fmt.Errorf("ebiten: height must be more than 0")
}
if width > graphics.ImageMaxSize {
return fmt.Errorf("ebiten: width must be less than or equal to %d", graphics.ImageMaxSize)
}
if height > graphics.ImageMaxSize {
return fmt.Errorf("ebiten: height must be less than or equal to %d", graphics.ImageMaxSize)
}
return nil
}
func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl, error) { func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl, error) {
if err := checkSize(width, height); err != nil {
return nil, err
}
img, err := restorable.NewImage(width, height, glFilter(filter), volatile) img, err := restorable.NewImage(width, height, glFilter(filter), volatile)
if err != nil { if err != nil {
return nil, err return nil, err
@ -47,7 +68,10 @@ func newImageImpl(width, height int, filter Filter, volatile bool) (*imageImpl,
func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error) { func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error) {
size := source.Bounds().Size() size := source.Bounds().Size()
w, h := size.X, size.Y w, h := size.X, size.Y
// TODO: Return error when the image is too big! if err := checkSize(w, h); err != nil {
return nil, err
}
// Don't lock while manipulating an image.Image interface. // Don't lock while manipulating an image.Image interface.
// It is necessary to copy the source image since the actual construction of // It is necessary to copy the source image since the actual construction of
@ -74,6 +98,10 @@ func newImageImplFromImage(source image.Image, filter Filter) (*imageImpl, error
} }
func newScreenImageImpl(width, height int) (*imageImpl, error) { func newScreenImageImpl(width, height int) (*imageImpl, error) {
if err := checkSize(width, height); err != nil {
return nil, err
}
img, err := restorable.NewScreenFramebufferImage(width, height) img, err := restorable.NewScreenFramebufferImage(width, height)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -29,6 +29,8 @@ type Image struct {
height int height int
} }
const ImageMaxSize = viewportSize
func NewImage(width, height int, filter opengl.Filter) (*Image, error) { func NewImage(width, height int, filter opengl.Filter) (*Image, error) {
i := &Image{ i := &Image{
width: width, width: width,