Index: Objects/stringlib/formatter.h =================================================================== --- Objects/stringlib/formatter.h (revision 70708) +++ Objects/stringlib/formatter.h (working copy) @@ -262,6 +262,8 @@ Py_ssize_t n_prefix, Py_ssize_t n_digits, const InternalFormatSpec *format) { + int no_sign_allowed = actual_sign == 'n' || actual_sign == 'i'; + spec->n_lpadding = 0; spec->n_prefix = 0; spec->n_spadding = 0; @@ -291,7 +293,7 @@ */ /* compute the various parts we're going to write */ - if (format->sign == '+') { + if (format->sign == '+' && !no_sign_allowed) { /* always put a + or - */ spec->n_lsign = 1; spec->lsign = (actual_sign == '-' ? '-' : '+'); @@ -369,9 +371,11 @@ STRINGLIB_FILL(p_buf, fill_char, spec->n_lpadding); p_buf += spec->n_lpadding; } + if (spec->n_lsign == 1) { *p_buf++ = spec->lsign; } + if (spec->n_prefix) { memmove(p_buf, prefix, @@ -781,7 +785,7 @@ if (x == -1.0 && PyErr_Occurred()) goto done; - if (type == '%') { + if (type == '%' && Py_IS_FINITE(x)) { type = 'f'; x *= 100; trailing = "%"; @@ -792,21 +796,28 @@ if (type == 'f' && fabs(x) >= 1e50) type = 'g'; - /* cast "type", because if we're in unicode we need to pass a - 8-bit char. this is safe, because we've restricted what "type" - can be */ - PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision, - (char)type); + if (Py_IS_NAN(x)) + strcpy(charbuf, "nan"); + else if (Py_IS_INFINITY(x)) { + if (x > 0) + strcpy(charbuf, "inf"); + else + strcpy(charbuf, "-inf"); + } else { + /* cast "type", because if we're in unicode we need to pass a 8-bit + char. this is safe, because we've restricted what "type" can be */ + PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", + precision, (char)type); + + /* do the actual formatting */ + PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); + + /* adding trailing to fmt with PyOS_snprintf doesn't work, not sure + why. we'll just concatentate it here, no harm done. we know we + can't have a buffer overflow from the fmt size analysis */ + strcat(charbuf, trailing); + } - /* do the actual formatting */ - PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x); - - /* adding trailing to fmt with PyOS_snprintf doesn't work, not - sure why. we'll just concatentate it here, no harm done. we - know we can't have a buffer overflow from the fmt size - analysis */ - strcat(charbuf, trailing); - /* rather than duplicate the code for snprintf for both unicode and 8 bit strings, we just use the 8 bit version and then convert to unicode in a separate code path. that's probably @@ -838,7 +849,8 @@ /* Fill in the non-digit parts (padding, sign, etc.) */ fill_non_digits(STRINGLIB_STR(result), &spec, NULL, n_digits, - format->fill_char == '\0' ? ' ' : format->fill_char); + (format->fill_char == '\0' || !Py_IS_FINITE(x)) + ? ' ' : format->fill_char); /* fill in the digit parts */ memmove(STRINGLIB_STR(result) +