video: Detect and reject nonsense SDL_surface dimensions Signed-off-by: Simon McVittie <smcv@collabora.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c
index cc20856..b2b5237 100644
--- a/src/video/SDL_surface.c
+++ b/src/video/SDL_surface.c
@@ -42,7 +42,7 @@ SDL_COMPILE_TIME_ASSERT(can_indicate_overflow, SDL_SIZE_MAX > SDL_MAX_SINT32);
* Return SDL_SIZE_MAX on overflow.
*/
static size_t
-SDL_CalculatePitch(Uint32 format, size_t width)
+SDL_CalculatePitch(Uint32 format, size_t width, SDL_bool minimal)
{
size_t pitch;
@@ -59,11 +59,13 @@ SDL_CalculatePitch(Uint32 format, size_t width)
}
pitch /= 8;
}
- /* 4-byte aligning for speed */
- if (SDL_size_add_overflow(pitch, 3, &pitch)) {
- return SDL_SIZE_MAX;
+ if (!minimal) {
+ /* 4-byte aligning for speed */
+ if (SDL_size_add_overflow(pitch, 3, &pitch)) {
+ return SDL_SIZE_MAX;
+ }
+ pitch &= ~3;
}
- pitch &= ~3;
return pitch;
}
@@ -81,7 +83,17 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth,
/* The flags are no longer used, make the compiler happy */
(void)flags;
- pitch = SDL_CalculatePitch(format, width);
+ if (width < 0) {
+ SDL_InvalidParamError("width");
+ return NULL;
+ }
+
+ if (height < 0) {
+ SDL_InvalidParamError("height");
+ return NULL;
+ }
+
+ pitch = SDL_CalculatePitch(format, width, SDL_FALSE);
if (pitch > SDL_MAX_SINT32) {
/* Overflow... */
SDL_OutOfMemory();
@@ -194,8 +206,34 @@ SDL_CreateRGBSurfaceFrom(void *pixels,
Uint32 Amask)
{
SDL_Surface *surface;
+ Uint32 format;
+ size_t minimalPitch;
- surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
+ if (width < 0) {
+ SDL_InvalidParamError("width");
+ return NULL;
+ }
+
+ if (height < 0) {
+ SDL_InvalidParamError("height");
+ return NULL;
+ }
+
+ format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
+
+ if (format == SDL_PIXELFORMAT_UNKNOWN) {
+ SDL_SetError("Unknown pixel format");
+ return NULL;
+ }
+
+ minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE);
+
+ if (pitch < 0 || ((size_t) pitch) < minimalPitch) {
+ SDL_InvalidParamError("pitch");
+ return NULL;
+ }
+
+ surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format);
if (surface != NULL) {
surface->flags |= SDL_PREALLOC;
surface->pixels = pixels;
@@ -217,6 +255,24 @@ SDL_CreateRGBSurfaceWithFormatFrom(void *pixels,
Uint32 format)
{
SDL_Surface *surface;
+ size_t minimalPitch;
+
+ if (width < 0) {
+ SDL_InvalidParamError("width");
+ return NULL;
+ }
+
+ if (height < 0) {
+ SDL_InvalidParamError("height");
+ return NULL;
+ }
+
+ minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE);
+
+ if (pitch < 0 || ((size_t) pitch) < minimalPitch) {
+ SDL_InvalidParamError("pitch");
+ return NULL;
+ }
surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format);
if (surface != NULL) {