Skip to content

Commit 1c5c3b1

Browse files
capehillslouken
authored andcommitted
Fix SDL_BlitSurfaceScaled crash
SDL_BlitSurfaceScaled could crash when passed large coordinates, due to final_dst.w or final_dst.h getting negative values.
1 parent d04899f commit 1c5c3b1

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/video/SDL_surface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1256,7 +1256,7 @@ bool SDL_BlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surfac
12561256
// Clip again
12571257
SDL_GetRectIntersection(clip_rect, &final_dst, &final_dst);
12581258

1259-
if (final_dst.w == 0 || final_dst.h == 0 ||
1259+
if (final_dst.w <= 0 || final_dst.h <= 0 ||
12601260
final_src.w < 0 || final_src.h < 0) {
12611261
// No-op.
12621262
return true;

test/testautomation_surface.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,45 @@ static int SDLCALL surface_testBlitInvalid(void *arg)
989989
return TEST_COMPLETED;
990990
}
991991

992+
static int SDLCALL surface_testBlitsWithBadCoordinates(void *arg)
993+
{
994+
const SDL_Rect rect[8] = {
995+
{ SDL_MAX_SINT32, 0, 2, 2 },
996+
{ 0, SDL_MAX_SINT32, 2, 2 },
997+
{ 0, 0, SDL_MAX_SINT32, 2 },
998+
{ 0, 0, 2, SDL_MAX_SINT32 },
999+
{ SDL_MIN_SINT32, 0, 2, 2 },
1000+
{ 0, SDL_MIN_SINT32, 2, 2 },
1001+
{ 0, 0, SDL_MIN_SINT32, 2 },
1002+
{ 0, 0, 2, SDL_MIN_SINT32 }
1003+
};
1004+
1005+
SDL_Surface *s;
1006+
bool result;
1007+
int i;
1008+
1009+
s = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA8888);
1010+
SDLTest_AssertCheck(s != NULL, "Check surface creation");
1011+
1012+
for (i = 0; i < 8; i++) {
1013+
result = SDL_BlitSurface(s, NULL, s, &rect[i]);
1014+
SDLTest_AssertCheck(result == true, "SDL_BlitSurface(valid, NULL, valid, &rect), result = %s", result ? "true" : "false");
1015+
1016+
result = SDL_BlitSurface(s, &rect[i], s, NULL);
1017+
SDLTest_AssertCheck(result == true, "SDL_BlitSurface(valid, &rect, valid, NULL), result = %s", result ? "true" : "false");
1018+
1019+
result = SDL_BlitSurfaceScaled(s, NULL, s, &rect[i], SDL_SCALEMODE_NEAREST);
1020+
SDLTest_AssertCheck(result == true, "SDL_BlitSurfaceScaled(valid, NULL, valid, &rect, SDL_SCALEMODE_NEAREST), result = %s", result ? "true" : "false");
1021+
1022+
result = SDL_BlitSurfaceScaled(s, &rect[i], s, NULL, SDL_SCALEMODE_NEAREST);
1023+
SDLTest_AssertCheck(result == true, "SDL_BlitSurfaceScaled(valid, &rect, valid, NULL, SDL_SCALEMODE_NEAREST), result = %s", result ? "true" : "false");
1024+
}
1025+
1026+
SDL_DestroySurface(s);
1027+
1028+
return TEST_COMPLETED;
1029+
}
1030+
9921031
static int SDLCALL surface_testOverflow(void *arg)
9931032
{
9941033
char buf[1024];
@@ -1666,6 +1705,10 @@ static const SDLTest_TestCaseReference surfaceTestBlitInvalid = {
16661705
surface_testBlitInvalid, "surface_testBlitInvalid", "Tests blitting routines with invalid surfaces.", TEST_ENABLED
16671706
};
16681707

1708+
static const SDLTest_TestCaseReference surfaceTestBlitsWithBadCoordinates = {
1709+
surface_testBlitsWithBadCoordinates, "surface_testBlitsWithBadCoordinates", "Test blitting routines with bad coordinates.", TEST_ENABLED
1710+
};
1711+
16691712
static const SDLTest_TestCaseReference surfaceTestOverflow = {
16701713
surface_testOverflow, "surface_testOverflow", "Test overflow detection.", TEST_ENABLED
16711714
};
@@ -1715,6 +1758,7 @@ static const SDLTest_TestCaseReference *surfaceTests[] = {
17151758
&surfaceTestBlitBlendMod,
17161759
&surfaceTestBlitBlendMul,
17171760
&surfaceTestBlitInvalid,
1761+
&surfaceTestBlitsWithBadCoordinates,
17181762
&surfaceTestOverflow,
17191763
&surfaceTestFlip,
17201764
&surfaceTestPalette,

0 commit comments

Comments
 (0)