Fix Bug 1533 - SDL_Keycode value range allows segfaults with negative values; add test coverage to keyboard suite
authorAndreas Schiffler <aschiffler@ferzkopp.net>
Fri, 08 Mar 2013 23:04:53 -0800
changeset 6983b72f56ab9867
parent 6982 9987a9daefb6
child 6984 ae9c4b12f3e2
Fix Bug 1533 - SDL_Keycode value range allows segfaults with negative values; add test coverage to keyboard suite
src/events/SDL_keyboard.c
test/testautomation_keyboard.c
     1.1 --- a/src/events/SDL_keyboard.c	Fri Mar 08 16:27:05 2013 -0800
     1.2 +++ b/src/events/SDL_keyboard.c	Fri Mar 08 23:04:53 2013 -0800
     1.3 @@ -861,7 +861,7 @@
     1.4  {
     1.5      SDL_Keyboard *keyboard = &SDL_keyboard;
     1.6      
     1.7 -    if (scancode<SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
     1.8 +    if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
     1.9            SDL_InvalidParamError("scancode");
    1.10            return 0;
    1.11      }
    1.12 @@ -887,8 +887,13 @@
    1.13  const char *
    1.14  SDL_GetScancodeName(SDL_Scancode scancode)
    1.15  {
    1.16 -    const char *name = SDL_scancode_names[scancode];
    1.17 +    const char *name;
    1.18 +    if (scancode < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
    1.19 +          SDL_InvalidParamError("scancode");
    1.20 +          return "";    
    1.21 +    }
    1.22  
    1.23 +    name = SDL_scancode_names[scancode];
    1.24      if (name)
    1.25          return name;
    1.26      else
     2.1 --- a/test/testautomation_keyboard.c	Fri Mar 08 16:27:05 2013 -0800
     2.2 +++ b/test/testautomation_keyboard.c	Fri Mar 08 23:04:53 2013 -0800
     2.3 @@ -3,6 +3,7 @@
     2.4   */
     2.5  
     2.6  #include <stdio.h>
     2.7 +#include <limits.h>
     2.8  
     2.9  #include "SDL_config.h"
    2.10  #include "SDL.h"
    2.11 @@ -103,6 +104,25 @@
    2.12     return TEST_COMPLETED;
    2.13  }
    2.14  
    2.15 +/* 
    2.16 + * Local helper to check for the invalid scancode error message
    2.17 + */
    2.18 +void
    2.19 +_checkInvalidScancodeError()
    2.20 +{
    2.21 +   const char *expectedError = "Parameter 'scancode' is invalid";
    2.22 +   const char *error;   
    2.23 +   error = SDL_GetError();
    2.24 +   SDLTest_AssertPass("Call to SDL_GetError()");
    2.25 +   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
    2.26 +   if (error != NULL) {
    2.27 +      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
    2.28 +          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
    2.29 +      SDL_ClearError();
    2.30 +      SDLTest_AssertPass("Call to SDL_ClearError()");
    2.31 +   }
    2.32 +}
    2.33 +
    2.34  /**
    2.35   * @brief Check call to SDL_GetKeyFromScancode
    2.36   * 
    2.37 @@ -111,8 +131,6 @@
    2.38  int
    2.39  keyboard_getKeyFromScancode(void *arg)
    2.40  {
    2.41 -   const char *expectedError = "Parameter 'scancode' is invalid";
    2.42 -   const char *error;   
    2.43     SDL_Keycode result;
    2.44  
    2.45     /* Case where input is valid */
    2.46 @@ -125,6 +143,7 @@
    2.47     SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(0)");
    2.48     SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result);
    2.49  
    2.50 +   /* Clear error message */
    2.51     SDL_ClearError();
    2.52     SDLTest_AssertPass("Call to SDL_ClearError()");
    2.53  
    2.54 @@ -132,31 +151,13 @@
    2.55     result = SDL_GetKeyFromScancode(-999);
    2.56     SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(-999)");
    2.57     SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result);
    2.58 -   error = SDL_GetError();
    2.59 -   SDLTest_AssertPass("Call to SDL_GetError()");
    2.60 -   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
    2.61 -   if (error != NULL) {
    2.62 -      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
    2.63 -          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
    2.64 -   }
    2.65 -
    2.66 -   SDL_ClearError();
    2.67 -   SDLTest_AssertPass("Call to SDL_ClearError()");
    2.68 +   _checkInvalidScancodeError();
    2.69  
    2.70     /* Case where input is invalid (too big) */
    2.71     result = SDL_GetKeyFromScancode(999);
    2.72     SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(999)");
    2.73     SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result);
    2.74 -   error = SDL_GetError();
    2.75 -   SDLTest_AssertPass("Call to SDL_GetError()");
    2.76 -   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
    2.77 -   if (error != NULL) {
    2.78 -      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
    2.79 -          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
    2.80 -   }
    2.81 -
    2.82 -   SDL_ClearError();
    2.83 -   SDLTest_AssertPass("Call to SDL_ClearError()");
    2.84 +   _checkInvalidScancodeError();
    2.85  
    2.86     return TEST_COMPLETED;
    2.87  }
    2.88 @@ -218,6 +219,78 @@
    2.89  }
    2.90  
    2.91  /**
    2.92 + * @brief SDL_GetScancodeName negative cases
    2.93 + * 
    2.94 + * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeName
    2.95 + */
    2.96 +int
    2.97 +keyboard_getScancodeNameNegative(void *arg)
    2.98 +{  
    2.99 +   SDL_Scancode scancode;
   2.100 +   char *result;
   2.101 +   char *expected = "";
   2.102 +
   2.103 +   /* Clear error message */
   2.104 +   SDL_ClearError();
   2.105 +   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.106 +
   2.107 +   /* Negative scancode */
   2.108 +   scancode = (SDL_Scancode)SDLTest_RandomIntegerInRange(LONG_MIN, -1);
   2.109 +   result = (char *)SDL_GetScancodeName(scancode);
   2.110 +   SDLTest_AssertPass("Call to SDL_GetScancodeName(%d/negative)", scancode);
   2.111 +   SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
   2.112 +   SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
   2.113 +   _checkInvalidScancodeError();
   2.114 +
   2.115 +   /* Large scancode */
   2.116 +   scancode = (SDL_Scancode)SDLTest_RandomIntegerInRange(SDL_NUM_SCANCODES, LONG_MAX);
   2.117 +   result = (char *)SDL_GetScancodeName(scancode);
   2.118 +   SDLTest_AssertPass("Call to SDL_GetScancodeName(%d/large)", scancode);
   2.119 +   SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
   2.120 +   SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
   2.121 +   _checkInvalidScancodeError();
   2.122 +
   2.123 +   return TEST_COMPLETED;
   2.124 +}
   2.125 +
   2.126 +/**
   2.127 + * @brief SDL_GetKeyName negative cases
   2.128 + * 
   2.129 + * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyName
   2.130 + */
   2.131 +int
   2.132 +keyboard_getKeyNameNegative(void *arg)
   2.133 +{  
   2.134 +   SDL_Keycode keycode;
   2.135 +   char *result;
   2.136 +   char *expected = "";
   2.137 +
   2.138 +   /* Unknown keycode */
   2.139 +   keycode = SDLK_UNKNOWN;
   2.140 +   result = (char *)SDL_GetKeyName(keycode);
   2.141 +   SDLTest_AssertPass("Call to SDL_GetKeyName(%d/unknown)", keycode);
   2.142 +   SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
   2.143 +   SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
   2.144 +
   2.145 +   /* Clear error message */
   2.146 +   SDL_ClearError();
   2.147 +   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.148 +
   2.149 +   /* Negative keycode */
   2.150 +   keycode = (SDL_Keycode)SDLTest_RandomIntegerInRange(-255, -1);
   2.151 +   result = (char *)SDL_GetKeyName(keycode);
   2.152 +   SDLTest_AssertPass("Call to SDL_GetKeyName(%d/negative)", keycode);
   2.153 +   SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL");
   2.154 +   SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result);
   2.155 +   _checkInvalidScancodeError();
   2.156 +
   2.157 +   SDL_ClearError();
   2.158 +   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.159 +
   2.160 +   return TEST_COMPLETED;
   2.161 +}
   2.162 +
   2.163 +/**
   2.164   * @brief Check call to SDL_GetModState and SDL_SetModState
   2.165   * 
   2.166   * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetModState
   2.167 @@ -521,6 +594,25 @@
   2.168     return TEST_COMPLETED;
   2.169  }
   2.170  
   2.171 +/* 
   2.172 + * Local helper to check for the invalid scancode error message
   2.173 + */
   2.174 +void
   2.175 +_checkInvalidNameError()
   2.176 +{
   2.177 +   const char *expectedError = "Parameter 'name' is invalid";
   2.178 +   const char *error;   
   2.179 +   error = SDL_GetError();
   2.180 +   SDLTest_AssertPass("Call to SDL_GetError()");
   2.181 +   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
   2.182 +   if (error != NULL) {
   2.183 +      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
   2.184 +          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
   2.185 +      SDL_ClearError();
   2.186 +      SDLTest_AssertPass("Call to SDL_ClearError()");
   2.187 +   }
   2.188 +}
   2.189 +
   2.190  /**
   2.191   * @brief Check call to SDL_GetScancodeFromName with invalid data
   2.192   * 
   2.193 @@ -532,9 +624,8 @@
   2.194  {      
   2.195     char *name;
   2.196     SDL_Scancode scancode;
   2.197 -   const char *expectedError = "Parameter 'name' is invalid";
   2.198 -   const char *error;
   2.199  
   2.200 +   /* Clear error message */
   2.201     SDL_ClearError();
   2.202     SDLTest_AssertPass("Call to SDL_ClearError()");
   2.203  
   2.204 @@ -548,48 +639,21 @@
   2.205     SDLTest_AssertPass("Call to SDL_GetScancodeFromName('%s')", name);
   2.206     SDL_free(name);
   2.207     SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode);
   2.208 -   error = SDL_GetError();
   2.209 -   SDLTest_AssertPass("Call to SDL_GetError()");
   2.210 -   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
   2.211 -   if (error != NULL) {
   2.212 -      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
   2.213 -          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
   2.214 -   }
   2.215 -
   2.216 -   SDL_ClearError();
   2.217 -   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.218 +   _checkInvalidNameError();
   2.219           
   2.220     /* Zero length string input */
   2.221     name = "";
   2.222     scancode = SDL_GetScancodeFromName((const char *)name);
   2.223     SDLTest_AssertPass("Call to SDL_GetScancodeFromName(NULL)");
   2.224     SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode);
   2.225 -   error = SDL_GetError();
   2.226 -   SDLTest_AssertPass("Call to SDL_GetError()");
   2.227 -   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
   2.228 -   if (error != NULL) {
   2.229 -      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
   2.230 -          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
   2.231 -   }
   2.232 -
   2.233 -   SDL_ClearError();
   2.234 -   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.235 +   _checkInvalidNameError();
   2.236  
   2.237     /* NULL input */
   2.238     name = NULL;
   2.239     scancode = SDL_GetScancodeFromName((const char *)name);
   2.240     SDLTest_AssertPass("Call to SDL_GetScancodeFromName(NULL)");
   2.241     SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode);
   2.242 -   error = SDL_GetError();
   2.243 -   SDLTest_AssertPass("Call to SDL_GetError()");
   2.244 -   SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL");
   2.245 -   if (error != NULL) {
   2.246 -      SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, 
   2.247 -          "Validate error message, expected: '%s', got: '%s'", expectedError, error);
   2.248 -   }
   2.249 -
   2.250 -   SDL_ClearError();
   2.251 -   SDLTest_AssertPass("Call to SDL_ClearError()");
   2.252 +   _checkInvalidNameError();
   2.253     
   2.254     return TEST_COMPLETED;
   2.255  }
   2.256 @@ -635,10 +699,17 @@
   2.257  static const SDLTest_TestCaseReference keyboardTest12 =
   2.258  		{ (SDLTest_TestCaseFp)keyboard_getScancodeFromNameNegative, "keyboard_getScancodeFromNameNegative", "Check call to SDL_GetScancodeFromName with invalid data", TEST_ENABLED };
   2.259  
   2.260 +static const SDLTest_TestCaseReference keyboardTest13 =
   2.261 +		{ (SDLTest_TestCaseFp)keyboard_getKeyNameNegative, "keyboard_getKeyNameNegative", "Check call to SDL_GetKeyName with invalid data", TEST_ENABLED };
   2.262 +
   2.263 +static const SDLTest_TestCaseReference keyboardTest14 =
   2.264 +		{ (SDLTest_TestCaseFp)keyboard_getScancodeNameNegative, "keyboard_getScancodeNameNegative", "Check call to SDL_GetScancodeName with invalid data", TEST_ENABLED };
   2.265 +
   2.266  /* Sequence of Keyboard test cases */
   2.267  static const SDLTest_TestCaseReference *keyboardTests[] =  {
   2.268  	&keyboardTest1, &keyboardTest2, &keyboardTest3, &keyboardTest4, &keyboardTest5, &keyboardTest6, 
   2.269 -	&keyboardTest7, &keyboardTest8, &keyboardTest9, &keyboardTest10, &keyboardTest11, &keyboardTest12, NULL
   2.270 +	&keyboardTest7, &keyboardTest8, &keyboardTest9, &keyboardTest10, &keyboardTest11, &keyboardTest12, 
   2.271 +	&keyboardTest13, &keyboardTest14, NULL
   2.272  };
   2.273  
   2.274  /* Keyboard test suite (global) */