Fixed bug 4283 - SDL's version of memset is different from libc's
authorSam Lantinga <slouken@libsdl.org>
Fri, 28 Sep 2018 20:48:18 -0700
changeset 122569f3949b8ec40
parent 12255 d2e5d4520677
child 12257 d7a3aac08fc1
Fixed bug 4283 - SDL's version of memset is different from libc's

janisozaur

memset's documentation reads:

* The memset() function shall copy c (converted to an unsigned char) into each of the first n bytes of the object pointed to by s. (http://pubs.opengroup.org/onlinepubs/9699919799/functions/memset.html)
* Sets the first count characters of dest to the character c. (https://msdn.microsoft.com/en-us/library/1fdeehz6.aspx)
* write a byte to a byte string (https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/memset.3.html)

The highlight here is they all mean a single _byte_, even though memset receives a parameter of type int, which can hold more data than a single byte. SDL's implementation of memset, however, does not clear any of the higher bits, causing an erroneous behaviour when passed an argument bigger than 0xff.
src/stdlib/SDL_string.c
     1.1 --- a/src/stdlib/SDL_string.c	Fri Sep 28 20:39:57 2018 -0700
     1.2 +++ b/src/stdlib/SDL_string.c	Fri Sep 28 20:48:18 2018 -0700
     1.3 @@ -271,12 +271,16 @@
     1.4      size_t left;
     1.5      Uint32 *dstp4;
     1.6      Uint8 *dstp1 = (Uint8 *) dst;
     1.7 -    Uint32 value4 = (c | (c << 8) | (c << 16) | (c << 24));
     1.8 -    Uint8 value1 = (Uint8) c;
     1.9 +    Uint8 value1;
    1.10 +    Uint32 value4;
    1.11 +
    1.12 +    /* The value used in memset() is a byte, passed as an int */
    1.13 +    c &= 0xff;
    1.14  
    1.15      /* The destination pointer needs to be aligned on a 4-byte boundary to
    1.16       * execute a 32-bit set. Set first bytes manually if needed until it is
    1.17       * aligned. */
    1.18 +    value1 = (Uint8)c;
    1.19      while ((intptr_t)dstp1 & 0x3) {
    1.20          if (len--) {
    1.21              *dstp1++ = value1;
    1.22 @@ -285,6 +289,7 @@
    1.23          }
    1.24      }
    1.25  
    1.26 +    value4 = (c | (c << 8) | (c << 16) | (c << 24));
    1.27      dstp4 = (Uint32 *) dstp1;
    1.28      left = (len % 4);
    1.29      len /= 4;