summaryrefslogtreecommitdiffstats
path: root/Python/formatter_unicode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/formatter_unicode.c')
-rw-r--r--Python/formatter_unicode.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
index 9fb840b..86385f6 100644
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -341,7 +341,7 @@ fill_padding(PyObject *s, Py_ssize_t start, Py_ssize_t nchars,
/* Pad on right. */
if (n_rpadding)
- unicode_fill(s, start + nchars + n_lpadding,
+ unicode_fill(s, start + nchars + n_lpadding,
start + nchars + n_lpadding + n_rpadding, fill_char);
/* Pointer to the user content. */
@@ -501,7 +501,7 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
spec->n_grouped_digits = 0;
else
spec->n_grouped_digits = _PyUnicode_InsertThousandsGrouping(
- PyUnicode_1BYTE_KIND, NULL, 0, NULL,
+ PyUnicode_1BYTE_KIND, NULL, 0, NULL,
spec->n_digits, spec->n_min_width,
locale->grouping, locale->thousands_sep);
@@ -541,11 +541,12 @@ calc_number_widths(NumberFieldWidths *spec, Py_ssize_t n_prefix,
/* Fill in the digit parts of a numbers's string representation,
as determined in calc_number_widths().
- No error checking, since we know the buffer is the correct size. */
-static void
+ Return -1 on error, or 0 on success. */
+static int
fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
PyObject *digits, Py_ssize_t d_start, Py_ssize_t d_end,
- PyObject *prefix, Py_ssize_t p_start, Py_UCS4 fill_char,
+ PyObject *prefix, Py_ssize_t p_start,
+ Py_UCS4 fill_char,
LocaleInfo *locale, int toupper)
{
/* Used to keep track of digits, decimal, and remainder. */
@@ -589,11 +590,8 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
char *pdigits = PyUnicode_DATA(digits);
if (PyUnicode_KIND(digits) < kind) {
pdigits = _PyUnicode_AsKind(digits, kind);
- if (pdigits == NULL) {
- /* XXX report exception */
- Py_FatalError("out of memory");
- return;
- }
+ if (pdigits == NULL)
+ return -1;
}
#ifndef NDEBUG
r =
@@ -640,6 +638,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
pos += spec->n_rpadding;
}
+ return 0;
}
static char no_grouping[1] = {CHAR_MAX};
@@ -765,6 +764,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
Py_ssize_t prefix;
NumberFieldWidths spec;
long x;
+ int err;
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
@@ -886,10 +886,13 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
goto done;
/* Populate the memory. */
- fill_number(result, 0, &spec, tmp, inumeric_chars, inumeric_chars + n_digits,
- tmp, prefix,
- format->fill_char == '\0' ? ' ' : format->fill_char,
- &locale, format->type == 'X');
+ err = fill_number(result, 0, &spec,
+ tmp, inumeric_chars, inumeric_chars + n_digits,
+ tmp, prefix,
+ format->fill_char == '\0' ? ' ' : format->fill_char,
+ &locale, format->type == 'X');
+ if (err)
+ Py_CLEAR(result);
done:
Py_XDECREF(tmp);
@@ -929,6 +932,7 @@ format_float_internal(PyObject *value,
Py_UCS4 sign_char = '\0';
int float_type; /* Used to see if we have a nan, inf, or regular float. */
PyObject *unicode_tmp = NULL;
+ int err;
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
@@ -1010,7 +1014,7 @@ format_float_internal(PyObject *value,
&locale);
/* Calculate how much memory we'll need. */
- n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
+ n_total = calc_number_widths(&spec, 0, sign_char, unicode_tmp, index,
index + n_digits, n_remainder, has_decimal,
&locale, format);
@@ -1020,10 +1024,13 @@ format_float_internal(PyObject *value,
goto done;
/* Populate the memory. */
- fill_number(result, 0, &spec, unicode_tmp, index, index + n_digits,
- NULL, 0,
- format->fill_char == '\0' ? ' ' : format->fill_char, &locale,
- 0);
+ err = fill_number(result, 0, &spec,
+ unicode_tmp, index, index + n_digits,
+ NULL, 0,
+ format->fill_char == '\0' ? ' ' : format->fill_char,
+ &locale, 0);
+ if (err)
+ Py_CLEAR(result);
done:
PyMem_Free(buf);
@@ -1077,6 +1084,7 @@ format_complex_internal(PyObject *value,
Py_ssize_t total;
PyObject *re_unicode_tmp = NULL;
PyObject *im_unicode_tmp = NULL;
+ int err;
/* Locale settings, either from the actual locale or
from a hard-code pseudo-locale */
@@ -1170,9 +1178,9 @@ format_complex_internal(PyObject *value,
/* Determine if we have any "remainder" (after the digits, might include
decimal or exponent or both (or neither)) */
- parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
+ parse_number(re_unicode_tmp, i_re, i_re + n_re_digits,
&n_re_remainder, &re_has_decimal);
- parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
+ parse_number(im_unicode_tmp, i_im, i_im + n_im_digits,
&n_im_remainder, &im_has_decimal);
/* Determine the grouping, separator, and decimal point, if any. */
@@ -1225,12 +1233,26 @@ format_complex_internal(PyObject *value,
PyUnicode_WRITE(rkind, rdata, index++, '(');
if (!skip_re) {
- fill_number(result, index, &re_spec, re_unicode_tmp,
- i_re, i_re + n_re_digits, NULL, 0, 0, &locale, 0);
+ err = fill_number(result, index, &re_spec,
+ re_unicode_tmp, i_re, i_re + n_re_digits,
+ NULL, 0,
+ 0,
+ &locale, 0);
+ if (err) {
+ Py_CLEAR(result);
+ goto done;
+ }
index += n_re_total;
}
- fill_number(result, index, &im_spec, im_unicode_tmp,
- i_im, i_im + n_im_digits, NULL, 0, 0, &locale, 0);
+ err = fill_number(result, index, &im_spec,
+ im_unicode_tmp, i_im, i_im + n_im_digits,
+ NULL, 0,
+ 0,
+ &locale, 0);
+ if (err) {
+ Py_CLEAR(result);
+ goto done;
+ }
index += n_im_total;
PyUnicode_WRITE(rkind, rdata, index++, 'j');