diff options
Diffstat (limited to 'lib/vasnprintf.c')
-rw-r--r-- | lib/vasnprintf.c | 199 |
1 files changed, 104 insertions, 95 deletions
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c index daea81642..7282b0504 100644 --- a/lib/vasnprintf.c +++ b/lib/vasnprintf.c @@ -1,5 +1,5 @@ /* vsprintf with automatic memory allocation. - Copyright (C) 1999, 2002-2015 Free Software Foundation, Inc. + Copyright (C) 1999, 2002-2014 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -1886,7 +1886,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, else { do - result[length++] = *cp++; + result[length++] = (unsigned char) *cp++; while (--n > 0); } } @@ -1957,14 +1957,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; - width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = -width; + width = (unsigned int) (-arg); } + else + width = arg; } else { @@ -2072,7 +2073,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (characters < width && !(dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2125,7 +2127,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (characters < width && (dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2198,7 +2201,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (characters < width && !(dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2251,7 +2255,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (characters < width && (dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2324,7 +2329,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (characters < width && !(dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2377,7 +2383,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } # endif - if (characters < width && (dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2428,14 +2435,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; - width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = -width; + width = (unsigned int) (-arg); } + else + width = arg; } else { @@ -2565,7 +2573,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, characters = 0; } - if (characters < width && !(dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && !(dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2626,7 +2635,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } } - if (characters < width && (dp->flags & FLAG_LEFT)) + if (has_width && width > characters + && (dp->flags & FLAG_LEFT)) { size_t n = width - characters; ENSURE_ALLOCATION (xsum (length, n)); @@ -2817,7 +2827,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* w doesn't matter. */ w = 0; - if (w < width && !(dp->flags & FLAG_LEFT)) + if (has_width && width > w + && !(dp->flags & FLAG_LEFT)) { size_t n = width - w; ENSURE_ALLOCATION (xsum (length, n)); @@ -2900,7 +2911,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, length += tmpdst_len; # endif - if (w < width && (dp->flags & FLAG_LEFT)) + if (has_width && width > w + && (dp->flags & FLAG_LEFT)) { size_t n = width - w; ENSURE_ALLOCATION (xsum (length, n)); @@ -2927,16 +2939,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; + int has_width; size_t width; int has_precision; size_t precision; size_t tmp_length; - size_t count; DCHAR_T tmpbuf[700]; DCHAR_T *tmp; DCHAR_T *pad_ptr; DCHAR_T *p; + has_width = 0; width = 0; if (dp->width_start != dp->width_end) { @@ -2947,14 +2960,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; - width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = -width; + width = (unsigned int) (-arg); } + else + width = arg; } else { @@ -2964,6 +2978,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } + has_width = 1; } has_precision = 0; @@ -3339,14 +3354,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, abort (); # endif } - /* The generated string now extends from tmp to p, with the zero padding insertion point being at pad_ptr. */ - count = p - tmp; - - if (count < width) + if (has_width && p - tmp < width) { - size_t pad = width - count; + size_t pad = width - (p - tmp); DCHAR_T *end = p + pad; if (flags & FLAG_LEFT) @@ -3379,26 +3391,28 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, p = end; } - count = p - tmp; + { + size_t count = p - tmp; - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); - ENSURE_ALLOCATION (n); - } + ENSURE_ALLOCATION (n); + } - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } } #endif #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL @@ -3432,8 +3446,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, arg_type type = a.arg[dp->arg_index].type; # endif int flags = dp->flags; + int has_width; size_t width; - size_t count; int has_precision; size_t precision; size_t tmp_length; @@ -3442,6 +3456,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, DCHAR_T *pad_ptr; DCHAR_T *p; + has_width = 0; width = 0; if (dp->width_start != dp->width_end) { @@ -3452,14 +3467,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; - width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = -width; + width = (unsigned int) (-arg); } + else + width = arg; } else { @@ -3469,6 +3485,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } + has_width = 1; } has_precision = 0; @@ -3908,9 +3925,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, digits without trailing zeroes. */ if (exponent >= 0) { - size_t ecount = exponent + 1; + size_t count = exponent + 1; /* Note: count <= precision = ndigits. */ - for (; ecount > 0; ecount--) + for (; count > 0; count--) *p++ = digits[--ndigits]; if ((flags & FLAG_ALT) || ndigits > nzeroes) { @@ -3924,10 +3941,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } else { - size_t ecount = -exponent - 1; + size_t count = -exponent - 1; *p++ = '0'; *p++ = decimal_point_char (); - for (; ecount > 0; ecount--) + for (; count > 0; count--) *p++ = '0'; while (ndigits > nzeroes) { @@ -4378,9 +4395,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, digits without trailing zeroes. */ if (exponent >= 0) { - size_t ecount = exponent + 1; - /* Note: ecount <= precision = ndigits. */ - for (; ecount > 0; ecount--) + size_t count = exponent + 1; + /* Note: count <= precision = ndigits. */ + for (; count > 0; count--) *p++ = digits[--ndigits]; if ((flags & FLAG_ALT) || ndigits > nzeroes) { @@ -4394,10 +4411,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, } else { - size_t ecount = -exponent - 1; + size_t count = -exponent - 1; *p++ = '0'; *p++ = decimal_point_char (); - for (; ecount > 0; ecount--) + for (; count > 0; count--) *p++ = '0'; while (ndigits > nzeroes) { @@ -4525,11 +4542,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* The generated string now extends from tmp to p, with the zero padding insertion point being at pad_ptr. */ - count = p - tmp; - - if (count < width) + if (has_width && p - tmp < width) { - size_t pad = width - count; + size_t pad = width - (p - tmp); DCHAR_T *end = p + pad; if (flags & FLAG_LEFT) @@ -4562,36 +4577,36 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, p = end; } - count = p - tmp; + { + size_t count = p - tmp; - if (count >= tmp_length) - /* tmp_length was incorrectly calculated - fix the - code above! */ - abort (); + if (count >= tmp_length) + /* tmp_length was incorrectly calculated - fix the + code above! */ + abort (); - /* Make room for the result. */ - if (count >= allocated - length) - { - size_t n = xsum (length, count); + /* Make room for the result. */ + if (count >= allocated - length) + { + size_t n = xsum (length, count); - ENSURE_ALLOCATION (n); - } + ENSURE_ALLOCATION (n); + } - /* Append the result. */ - memcpy (result + length, tmp, count * sizeof (DCHAR_T)); - if (tmp != tmpbuf) - free (tmp); - length += count; + /* Append the result. */ + memcpy (result + length, tmp, count * sizeof (DCHAR_T)); + if (tmp != tmpbuf) + free (tmp); + length += count; + } } #endif else { arg_type type = a.arg[dp->arg_index].type; int flags = dp->flags; -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - int has_width; -#endif #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + int has_width; size_t width; #endif #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION @@ -4620,10 +4635,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, TCHAR_T *tmp; #endif -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION - has_width = 0; -#endif #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION + has_width = 0; width = 0; if (dp->width_start != dp->width_end) { @@ -4634,14 +4647,15 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, if (!(a.arg[dp->width_arg_index].type == TYPE_INT)) abort (); arg = a.arg[dp->width_arg_index].a.a_int; - width = arg; if (arg < 0) { /* "A negative field width is taken as a '-' flag followed by a positive field width." */ flags |= FLAG_LEFT; - width = -width; + width = (unsigned int) (-arg); } + else + width = arg; } else { @@ -4651,9 +4665,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, width = xsum (xtimes (width, 10), *digitp++ - '0'); while (digitp != dp->width_end); } -#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION has_width = 1; -#endif } #endif @@ -4793,7 +4805,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { const FCHAR_T *mp = dp->width_start; do - *fbp++ = *mp++; + *fbp++ = (unsigned char) *mp++; while (--n > 0); } } @@ -4814,7 +4826,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, { const FCHAR_T *mp = dp->precision_start; do - *fbp++ = *mp++; + *fbp++ = (unsigned char) *mp++; while (--n > 0); } } @@ -5141,7 +5153,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, size_t tmp_length = MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type, flags, - width, + has_width ? width : 0, has_precision, precision, pad_ourselves); @@ -5179,21 +5191,18 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, /* SNPRINTF or sprintf failed. Save and use the errno that it has set, if any. */ int saved_errno = errno; - if (saved_errno == 0) - { - if (dp->conversion == 'c' || dp->conversion == 's') - saved_errno = EILSEQ; - else - saved_errno = EINVAL; - } if (!(result == resultbuf || result == NULL)) free (result); if (buf_malloced != NULL) free (buf_malloced); CLEANUP (); - - errno = saved_errno; + errno = + (saved_errno != 0 + ? saved_errno + : (dp->conversion == 'c' || dp->conversion == 's' + ? EILSEQ + : EINVAL)); return NULL; } @@ -5382,7 +5391,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp, tmpsrc += count; tmpdst += count; for (n = count; n > 0; n--) - *--tmpdst = *--tmpsrc; + *--tmpdst = (unsigned char) *--tmpsrc; } } #endif |