SDL_vsnprintf: fix numerics if both zero-padding and a field are given.
authorOzkan Sezer <sezeroz@gmail.com>
Sat, 29 Sep 2018 00:51:24 +0300
changeset 122532dbf011db466
parent 12252 9a334644da3e
child 12254 f1ac9de30ee1
SDL_vsnprintf: fix numerics if both zero-padding and a field are given.

it used to place zeroes between the sign and the number. (space-padding
from within SDL_PrintString() seems OK: spaces are added before sign.)

also fixed the maxlen handling if the number has a sign.
src/stdlib/SDL_string.c
     1.1 --- a/src/stdlib/SDL_string.c	Fri Sep 28 17:01:24 2018 +0300
     1.2 +++ b/src/stdlib/SDL_string.c	Sat Sep 29 00:51:24 2018 +0300
     1.3 @@ -1416,15 +1416,19 @@
     1.4  static void
     1.5  SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info)
     1.6  {/* left-pad num with zeroes. */
     1.7 -    size_t sz, pad;
     1.8 +    size_t sz, pad, have_sign;
     1.9  
    1.10 -    if (!info || info->precision < 0)
    1.11 +    if (!info)
    1.12          return;
    1.13  
    1.14 -    if (*num == '-')
    1.15 +    have_sign = 0;
    1.16 +    if (*num == '-' || *num == '+') {
    1.17 +        have_sign = 1;
    1.18          ++num;
    1.19 +        --maxlen;
    1.20 +    }
    1.21      sz = SDL_strlen(num);
    1.22 -    if (sz < (size_t)info->precision) {
    1.23 +    if (info->precision > 0 && sz < (size_t)info->precision) {
    1.24          pad = (size_t)info->precision - sz;
    1.25          if (pad + sz + 1 <= maxlen) { /* otherwise ignore the precision */
    1.26              SDL_memmove(num + pad, num, sz + 1);
    1.27 @@ -1432,6 +1436,18 @@
    1.28          }
    1.29      }
    1.30      info->precision = -1;/* so that SDL_PrintString() doesn't make a mess. */
    1.31 +
    1.32 +    if (info->pad_zeroes && info->width > 0 && (size_t)info->width > sz + have_sign) {
    1.33 +    /* handle here: spaces are added before the sign
    1.34 +       but zeroes must be placed _after_ the sign. */
    1.35 +    /* sz hasn't changed: we ignore pad_zeroes if a precision is given. */
    1.36 +        pad = (size_t)info->width - sz - have_sign;
    1.37 +        if (pad + sz + 1 <= maxlen) {
    1.38 +            SDL_memmove(num + pad, num, sz + 1);
    1.39 +            SDL_memset(num, '0', pad);
    1.40 +        }
    1.41 +        info->width = 0; /* so that SDL_PrintString() doesn't make a mess. */
    1.42 +    }
    1.43  }
    1.44  
    1.45  static size_t