src/SDL.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 18 Feb 2019 07:50:33 -0800
changeset 12612 07c39cbbeacf
parent 12503 806492103856
child 12630 a26e3c61e35f
permissions -rw-r--r--
Fixed bug 4500 - Heap-Buffer Overflow in Map1toN pertaining to SDL_pixels.c

Petr Pisar

The reproducer has these data in BITMAPINFOHEADER:

biSize = 40
biBitCount = 8
biClrUsed = 131075

SDL_LoadBMP_RW() function passes biBitCount as a color depth to SDL_CreateRGBSurface(), thus 256-color pallete is allocated. But then biClrUsed colors are read from a file and stored into the palette. SDL_LoadBMP_RW should report an error if biClrUsed is greater than 2^biBitCount.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "./SDL_internal.h"
    22 
    23 #if defined(__WIN32__)
    24 #include "core/windows/SDL_windows.h"
    25 #endif
    26 
    27 /* Initialization code for SDL */
    28 
    29 #include "SDL.h"
    30 #include "SDL_bits.h"
    31 #include "SDL_revision.h"
    32 #include "SDL_assert_c.h"
    33 #include "events/SDL_events_c.h"
    34 #include "haptic/SDL_haptic_c.h"
    35 #include "joystick/SDL_joystick_c.h"
    36 #include "sensor/SDL_sensor_c.h"
    37 
    38 /* Initialization/Cleanup routines */
    39 #if !SDL_TIMERS_DISABLED
    40 # include "timer/SDL_timer_c.h"
    41 #endif
    42 #if SDL_VIDEO_DRIVER_WINDOWS
    43 extern int SDL_HelperWindowCreate(void);
    44 extern int SDL_HelperWindowDestroy(void);
    45 #endif
    46 
    47 
    48 /* The initialized subsystems */
    49 #ifdef SDL_MAIN_NEEDED
    50 static SDL_bool SDL_MainIsReady = SDL_FALSE;
    51 #else
    52 static SDL_bool SDL_MainIsReady = SDL_TRUE;
    53 #endif
    54 static SDL_bool SDL_bInMainQuit = SDL_FALSE;
    55 static Uint8 SDL_SubsystemRefCount[ 32 ];
    56 
    57 /* Private helper to increment a subsystem's ref counter. */
    58 static void
    59 SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem)
    60 {
    61     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    62     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    63     ++SDL_SubsystemRefCount[subsystem_index];
    64 }
    65 
    66 /* Private helper to decrement a subsystem's ref counter. */
    67 static void
    68 SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem)
    69 {
    70     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    71     if (SDL_SubsystemRefCount[subsystem_index] > 0) {
    72         --SDL_SubsystemRefCount[subsystem_index];
    73     }
    74 }
    75 
    76 /* Private helper to check if a system needs init. */
    77 static SDL_bool
    78 SDL_PrivateShouldInitSubsystem(Uint32 subsystem)
    79 {
    80     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    81     SDL_assert(SDL_SubsystemRefCount[subsystem_index] < 255);
    82     return (SDL_SubsystemRefCount[subsystem_index] == 0) ? SDL_TRUE : SDL_FALSE;
    83 }
    84 
    85 /* Private helper to check if a system needs to be quit. */
    86 static SDL_bool
    87 SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) {
    88     int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
    89     if (SDL_SubsystemRefCount[subsystem_index] == 0) {
    90       return SDL_FALSE;
    91     }
    92 
    93     /* If we're in SDL_Quit, we shut down every subsystem, even if refcount
    94      * isn't zero.
    95      */
    96     return (SDL_SubsystemRefCount[subsystem_index] == 1 || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE;
    97 }
    98 
    99 void
   100 SDL_SetMainReady(void)
   101 {
   102     SDL_MainIsReady = SDL_TRUE;
   103 }
   104 
   105 int
   106 SDL_InitSubSystem(Uint32 flags)
   107 {
   108     if (!SDL_MainIsReady) {
   109         SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?");
   110         return -1;
   111     }
   112 
   113     /* Clear the error message */
   114     SDL_ClearError();
   115 
   116     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   117         /* game controller implies joystick */
   118         flags |= SDL_INIT_JOYSTICK;
   119     }
   120 
   121     if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
   122         /* video or joystick implies events */
   123         flags |= SDL_INIT_EVENTS;
   124     }
   125 
   126 #if SDL_VIDEO_DRIVER_WINDOWS
   127     if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
   128         if (SDL_HelperWindowCreate() < 0) {
   129             return -1;
   130         }
   131     }
   132 #endif
   133 
   134 #if !SDL_TIMERS_DISABLED
   135     SDL_TicksInit();
   136 #endif
   137 
   138     /* Initialize the event subsystem */
   139     if ((flags & SDL_INIT_EVENTS)) {
   140 #if !SDL_EVENTS_DISABLED
   141         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) {
   142             if (SDL_StartEventLoop() < 0) {
   143                 return (-1);
   144             }
   145             SDL_QuitInit();
   146         }
   147         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS);
   148 #else
   149         return SDL_SetError("SDL not built with events support");
   150 #endif
   151     }
   152 
   153     /* Initialize the timer subsystem */
   154     if ((flags & SDL_INIT_TIMER)){
   155 #if !SDL_TIMERS_DISABLED
   156         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) {
   157             if (SDL_TimerInit() < 0) {
   158                 return (-1);
   159             }
   160         }
   161         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER);
   162 #else
   163         return SDL_SetError("SDL not built with timer support");
   164 #endif
   165     }
   166 
   167     /* Initialize the video subsystem */
   168     if ((flags & SDL_INIT_VIDEO)){
   169 #if !SDL_VIDEO_DISABLED
   170         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) {
   171             if (SDL_VideoInit(NULL) < 0) {
   172                 return (-1);
   173             }
   174         }
   175         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO);
   176 #else
   177         return SDL_SetError("SDL not built with video support");
   178 #endif
   179     }
   180 
   181     /* Initialize the audio subsystem */
   182     if ((flags & SDL_INIT_AUDIO)){
   183 #if !SDL_AUDIO_DISABLED
   184         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) {
   185             if (SDL_AudioInit(NULL) < 0) {
   186                 return (-1);
   187             }
   188         }
   189         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO);
   190 #else
   191         return SDL_SetError("SDL not built with audio support");
   192 #endif
   193     }
   194 
   195     /* Initialize the joystick subsystem */
   196     if ((flags & SDL_INIT_JOYSTICK)){
   197 #if !SDL_JOYSTICK_DISABLED
   198         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) {
   199            if (SDL_JoystickInit() < 0) {
   200                return (-1);
   201            }
   202         }
   203         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK);
   204 #else
   205         return SDL_SetError("SDL not built with joystick support");
   206 #endif
   207     }
   208 
   209     if ((flags & SDL_INIT_GAMECONTROLLER)){
   210 #if !SDL_JOYSTICK_DISABLED
   211         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   212             if (SDL_GameControllerInit() < 0) {
   213                 return (-1);
   214             }
   215         }
   216         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER);
   217 #else
   218         return SDL_SetError("SDL not built with joystick support");
   219 #endif
   220     }
   221 
   222     /* Initialize the haptic subsystem */
   223     if ((flags & SDL_INIT_HAPTIC)){
   224 #if !SDL_HAPTIC_DISABLED
   225         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) {
   226             if (SDL_HapticInit() < 0) {
   227                 return (-1);
   228             }
   229         }
   230         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC);
   231 #else
   232         return SDL_SetError("SDL not built with haptic (force feedback) support");
   233 #endif
   234     }
   235 
   236     /* Initialize the sensor subsystem */
   237     if ((flags & SDL_INIT_SENSOR)){
   238 #if !SDL_SENSOR_DISABLED
   239         if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) {
   240             if (SDL_SensorInit() < 0) {
   241                 return (-1);
   242             }
   243         }
   244         SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR);
   245 #else
   246         return SDL_SetError("SDL not built with sensor support");
   247 #endif
   248     }
   249 
   250     return (0);
   251 }
   252 
   253 int
   254 SDL_Init(Uint32 flags)
   255 {
   256     return SDL_InitSubSystem(flags);
   257 }
   258 
   259 void
   260 SDL_QuitSubSystem(Uint32 flags)
   261 {
   262     /* Shut down requested initialized subsystems */
   263 #if !SDL_SENSOR_DISABLED
   264     if ((flags & SDL_INIT_SENSOR)) {
   265         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
   266             SDL_SensorQuit();
   267         }
   268         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
   269     }
   270 #endif
   271 
   272 #if !SDL_JOYSTICK_DISABLED
   273     if ((flags & SDL_INIT_GAMECONTROLLER)) {
   274         /* game controller implies joystick */
   275         flags |= SDL_INIT_JOYSTICK;
   276 
   277         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) {
   278             SDL_GameControllerQuit();
   279         }
   280         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER);
   281     }
   282 
   283     if ((flags & SDL_INIT_JOYSTICK)) {
   284         /* joystick implies events */
   285         flags |= SDL_INIT_EVENTS;
   286 
   287         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) {
   288             SDL_JoystickQuit();
   289         }
   290         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK);
   291     }
   292 #endif
   293 
   294 #if !SDL_HAPTIC_DISABLED
   295     if ((flags & SDL_INIT_HAPTIC)) {
   296         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) {
   297             SDL_HapticQuit();
   298         }
   299         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC);
   300     }
   301 #endif
   302 
   303 #if !SDL_AUDIO_DISABLED
   304     if ((flags & SDL_INIT_AUDIO)) {
   305         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) {
   306             SDL_AudioQuit();
   307         }
   308         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO);
   309     }
   310 #endif
   311 
   312 #if !SDL_VIDEO_DISABLED
   313     if ((flags & SDL_INIT_VIDEO)) {
   314         /* video implies events */
   315         flags |= SDL_INIT_EVENTS;
   316 
   317         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) {
   318             SDL_VideoQuit();
   319         }
   320         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO);
   321     }
   322 #endif
   323 
   324 #if !SDL_TIMERS_DISABLED
   325     if ((flags & SDL_INIT_TIMER)) {
   326         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) {
   327             SDL_TimerQuit();
   328         }
   329         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER);
   330     }
   331 #endif
   332 
   333 #if !SDL_EVENTS_DISABLED
   334     if ((flags & SDL_INIT_EVENTS)) {
   335         if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) {
   336             SDL_QuitQuit();
   337             SDL_StopEventLoop();
   338         }
   339         SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS);
   340     }
   341 #endif
   342 }
   343 
   344 Uint32
   345 SDL_WasInit(Uint32 flags)
   346 {
   347     int i;
   348     int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount);
   349     Uint32 initialized = 0;
   350 
   351     /* Fast path for checking one flag */
   352     if (SDL_HasExactlyOneBitSet32(flags)) {
   353         int subsystem_index = SDL_MostSignificantBitIndex32(flags);
   354         return SDL_SubsystemRefCount[subsystem_index] ? flags : 0;
   355     }
   356 
   357     if (!flags) {
   358         flags = SDL_INIT_EVERYTHING;
   359     }
   360 
   361     num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1);
   362 
   363     /* Iterate over each bit in flags, and check the matching subsystem. */
   364     for (i = 0; i < num_subsystems; ++i) {
   365         if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) {
   366             initialized |= (1 << i);
   367         }
   368 
   369         flags >>= 1;
   370     }
   371 
   372     return initialized;
   373 }
   374 
   375 void
   376 SDL_Quit(void)
   377 {
   378     SDL_bInMainQuit = SDL_TRUE;
   379 
   380     /* Quit all subsystems */
   381 #if SDL_VIDEO_DRIVER_WINDOWS
   382     SDL_HelperWindowDestroy();
   383 #endif
   384     SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
   385 
   386 #if !SDL_TIMERS_DISABLED
   387     SDL_TicksQuit();
   388 #endif
   389 
   390     SDL_ClearHints();
   391     SDL_AssertionsQuit();
   392     SDL_LogResetPriorities();
   393 
   394     /* Now that every subsystem has been quit, we reset the subsystem refcount
   395      * and the list of initialized subsystems.
   396      */
   397     SDL_memset( SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount) );
   398 
   399     SDL_bInMainQuit = SDL_FALSE;
   400 }
   401 
   402 /* Get the library version number */
   403 void
   404 SDL_GetVersion(SDL_version * ver)
   405 {
   406     SDL_VERSION(ver);
   407 }
   408 
   409 /* Get the library source revision */
   410 const char *
   411 SDL_GetRevision(void)
   412 {
   413     return SDL_REVISION;
   414 }
   415 
   416 /* Get the library source revision number */
   417 int
   418 SDL_GetRevisionNumber(void)
   419 {
   420     return SDL_REVISION_NUMBER;
   421 }
   422 
   423 /* Get the name of the platform */
   424 const char *
   425 SDL_GetPlatform()
   426 {
   427 #if __AIX__
   428     return "AIX";
   429 #elif __ANDROID__
   430     return "Android";
   431 #elif __BSDI__
   432     return "BSDI";
   433 #elif __DREAMCAST__
   434     return "Dreamcast";
   435 #elif __EMSCRIPTEN__
   436     return "Emscripten";
   437 #elif __FREEBSD__
   438     return "FreeBSD";
   439 #elif __HAIKU__
   440     return "Haiku";
   441 #elif __HPUX__
   442     return "HP-UX";
   443 #elif __IRIX__
   444     return "Irix";
   445 #elif __LINUX__
   446     return "Linux";
   447 #elif __MINT__
   448     return "Atari MiNT";
   449 #elif __MACOS__
   450     return "MacOS Classic";
   451 #elif __MACOSX__
   452     return "Mac OS X";
   453 #elif __NACL__
   454     return "NaCl";
   455 #elif __NETBSD__
   456     return "NetBSD";
   457 #elif __OPENBSD__
   458     return "OpenBSD";
   459 #elif __OS2__
   460     return "OS/2";
   461 #elif __OSF__
   462     return "OSF/1";
   463 #elif __QNXNTO__
   464     return "QNX Neutrino";
   465 #elif __RISCOS__
   466     return "RISC OS";
   467 #elif __SOLARIS__
   468     return "Solaris";
   469 #elif __WIN32__
   470     return "Windows";
   471 #elif __WINRT__
   472     return "WinRT";
   473 #elif __TVOS__
   474     return "tvOS";
   475 #elif __IPHONEOS__
   476     return "iOS";
   477 #elif __PSP__
   478     return "PlayStation Portable";
   479 #else
   480     return "Unknown (see SDL_platform.h)";
   481 #endif
   482 }
   483 
   484 SDL_bool
   485 SDL_IsTablet()
   486 {
   487 #if __ANDROID__
   488     extern SDL_bool SDL_IsAndroidTablet(void);
   489     return SDL_IsAndroidTablet();
   490 #elif __IPHONEOS__
   491     extern SDL_bool SDL_IsIPad(void);
   492     return SDL_IsIPad();
   493 #else
   494     return SDL_FALSE;
   495 #endif
   496 }
   497 
   498 #if defined(__WIN32__)
   499 
   500 #if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
   501 /* Need to include DllMain() on Watcom C for some reason.. */
   502 
   503 BOOL APIENTRY
   504 _DllMainCRTStartup(HANDLE hModule,
   505                    DWORD ul_reason_for_call, LPVOID lpReserved)
   506 {
   507     switch (ul_reason_for_call) {
   508     case DLL_PROCESS_ATTACH:
   509     case DLL_THREAD_ATTACH:
   510     case DLL_THREAD_DETACH:
   511     case DLL_PROCESS_DETACH:
   512         break;
   513     }
   514     return TRUE;
   515 }
   516 #endif /* Building DLL */
   517 
   518 #endif /* __WIN32__ */
   519 
   520 /* vi: set sts=4 ts=4 sw=4 expandtab: */