We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1534

Summary: SIGSEGV in SDL_ConvertSurface() for certain formats in SDL2
Product: SDL Reporter: Marcus von Appen <mva>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: major    
Priority: P2 CC: gabomdq
Version: HG 2.0   
Hardware: All   
OS: All   
Attachments: SDL_ConvertSurface() SIGSEGV test program
Only use Blit1* functions to blit to/from palette based formats
Only use Blit0*/Blit1* functions to blit from palette based formats

Description Marcus von Appen 2012-07-03 03:34:11 UTC
Created attachment 894 [details]
SDL_ConvertSurface() SIGSEGV test program

Using SDL_ConvertSurface() to convert from SDL_PIXELFORMAT_RGB444
to SDL_PIXELFORMAT_RGB332 or SDL_PIXELFORMAT_ARGB2101010 causes a SIGSEGV in
the DUFFS_LOOP unrolled code segments.

The problem can be reproduced on Win32 platforms, Linux and BSD, x64 builds,
with the attached test program.

Other source pixel formats were not tested yet.

gdb backtrace:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 800e041c0 (LWP 100441/initial thread)]
0x00000008006d9017 in Blit1to2 (info=0x800e2fd20)
    at ../src/video/SDL_blit_1.c:103
103			DUFFS_LOOP(
(gdb) bt
#0  0x00000008006d9017 in Blit1to2 (info=0x800e2fd20)
    at ../src/video/SDL_blit_1.c:103
#1  0x00000008006d7146 in SDL_SoftBlit (src=0x800f2e5e0, 
    srcrect=0x7fffffffe6c0, dst=0x800f2e580, dstrect=0x7fffffffe6c0)
    at ../src/video/SDL_blit.c:88
#2  0x000000080072079f in SDL_LowerBlit (src=0x800f2e5e0, 
    srcrect=0x7fffffffe6c0, dst=0x800f2e580, dstrect=0x7fffffffe6c0)
    at ../src/video/SDL_surface.c:494
#3  0x0000000800721116 in SDL_ConvertSurface (surface=0x800f2e5e0, 
    format=0x800ef0900, flags=0) at ../src/video/SDL_surface.c:811
#4  0x00000000004009b4 in main (argc=1, argv=0x7fffffffe7a8) at main.c:35
Comment 1 Marcus von Appen 2013-04-24 05:31:29 UTC
Are there any news on this bug?
Comment 2 Gabriel Jacobo 2013-04-26 10:44:07 UTC
Created attachment 1125 [details]
Only use Blit1* functions to blit to/from palette based formats

The attached patch solves the SIGSEGV.

The problem is that SDL_MapSurface doesn't create a map for the formats you are using (SDL_PIXELFORMAT_RGB332 and SDL_PIXELFORMAT_RGB444), given currently it only checks if either of those formats are indexed/palette based, and if they are not it checks if both formats are the same. If they are not the same, it just keeps on going, without setting a transformation nor failing (should it return -1 in this case? )

The patch forces SDL_CalculateBlit to skip SDL_CalculateBlit1 (which returns functions that seem to be conversion map based, and depend on SDL_MapSurface to set a correct map), and instead it uses SDL_Blit_Slow unconditionally (previously there was a check, which the patch removes, to see if bytes per pixel was > 1, though there's nothing in SDL_Blit_Slow indicating that the function can't handle BPP==1).

Anyway, it seems to work here (I traced through SDL_Blit_Slow and it seems to be doing something reasonable) though I haven't checked the resulting image.

I'm leaving the patch here for Sam or Ryan to review or if anyone else is more familiarized with the surface conversion code, speak up!
Comment 3 Gabriel Jacobo 2013-04-26 10:48:40 UTC
Another possible fix, instead of checking if SDL_ISPIXELFORMAT_INDEXED would be checking if map->info.table != NULL (which would be more generic)
Comment 4 Gabriel Jacobo 2013-05-21 10:03:12 UTC
Created attachment 1147 [details]
Only use Blit0*/Blit1* functions to blit from palette based formats
Comment 5 Sam Lantinga 2013-05-22 01:05:45 UTC
Fixed!
http://hg.libsdl.org/SDL/rev/414ad123be9b

Gabriel, I went with the INDEXED check instead of checking for the map table because I want to catch any problems where it's an indexed format without a mapping table.

Thanks everyone! :)
Comment 6 Marcus von Appen 2013-05-27 02:26:29 UTC
Unfortunately another crash occurs, for the combination of SDL_PIXELFORMAT_INDEX8 and SDL_PIXELFORMAT_ARGB2101010:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 805c07400 (LWP 100806/foo)]
0x00000008008dfd2e in BlitNto1 (info=0x805d5c320)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_N.c:2005
2005	            DUFFS_LOOP(
(gdb) bt
#0  0x00000008008dfd2e in BlitNto1 (info=0x805d5c320)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_N.c:2005
#1  0x00000008008c1f86 in SDL_SoftBlit (src=0x806feb1c0, 
    srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit.c:88
#2  0x000000080090878f in SDL_LowerBlit (src=0x806feb1c0, 
    srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_surface.c:506
#3  0x000000080090918d in SDL_ConvertSurface (surface=0x806feb1c0, 
    format=0x805cd34c0, flags=0)

Within the test program, simply change SDL_PIXELFORMAT_RGB332 to SDL_PIXELFORMAT_ARGB2101010 and SDL_PIXELFORMAT_RGB444 to SDL_PIXELFORMAT_INDEX8.
Comment 7 Marcus von Appen 2013-05-27 02:31:23 UTC
And another one:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 805c07400 (LWP 100775/foo)]
0x000000080091120a in SDL_Blit_Slow (info=0x805d5c320)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_slow.c:95
95	                DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
(gdb) bt
#0  0x000000080091120a in SDL_Blit_Slow (info=0x805d5c320)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit_slow.c:95
#1  0x00000008008c1f86 in SDL_SoftBlit (src=0x806feb1c0, 
    srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_blit.c:88
#2  0x000000080090878f in SDL_LowerBlit (src=0x806feb1c0, 
    srcrect=0x7fffffffd610, dst=0x806feb220, dstrect=0x7fffffffd610)
    at /home/marcus/devel/projects/extern/SDL/src/video/SDL_surface.c:506
#3  0x000000080090918d in SDL_ConvertSurface (surface=0x806feb1c0, 
    format=0x805cd34c0, flags=0)

for the combination SDL_PIXELFORMAT_RGB332 to SDL_PIXELFORMAT_ARGB2101010.
Comment 8 Sam Lantinga 2013-07-07 15:37:58 UTC
Okay, I fixed surface conversion with SDL_PIXELFORMAT_ARGB2101010, and added an automated test to cover converting between all supported pixel formats.

Thanks!