Commit 9a55cd88 authored by Eric V. Smith's avatar Eric V. Smith

Issue #12546: Allow \x00 as a fill character for builtin type __format__ methods.

parent 6c939cb6
...@@ -1463,6 +1463,27 @@ class UnicodeTest( ...@@ -1463,6 +1463,27 @@ class UnicodeTest(
self.assertEqual(u'{0:10000}'.format(u''), u' ' * 10000) self.assertEqual(u'{0:10000}'.format(u''), u' ' * 10000)
self.assertEqual(u'{0:10000000}'.format(u''), u' ' * 10000000) self.assertEqual(u'{0:10000000}'.format(u''), u' ' * 10000000)
# issue 12546: use \x00 as a fill character
self.assertEqual('{0:\x00<6s}'.format('foo'), 'foo\x00\x00\x00')
self.assertEqual('{0:\x01<6s}'.format('foo'), 'foo\x01\x01\x01')
self.assertEqual('{0:\x00^6s}'.format('foo'), '\x00foo\x00\x00')
self.assertEqual('{0:^6s}'.format('foo'), ' foo ')
self.assertEqual('{0:\x00<6}'.format(3), '3\x00\x00\x00\x00\x00')
self.assertEqual('{0:\x01<6}'.format(3), '3\x01\x01\x01\x01\x01')
self.assertEqual('{0:\x00^6}'.format(3), '\x00\x003\x00\x00\x00')
self.assertEqual('{0:<6}'.format(3), '3 ')
self.assertEqual('{0:\x00<6}'.format(3.14), '3.14\x00\x00')
self.assertEqual('{0:\x01<6}'.format(3.14), '3.14\x01\x01')
self.assertEqual('{0:\x00^6}'.format(3.14), '\x003.14\x00')
self.assertEqual('{0:^6}'.format(3.14), ' 3.14 ')
self.assertEqual('{0:\x00<12}'.format(3+2.0j), '(3+2j)\x00\x00\x00\x00\x00\x00')
self.assertEqual('{0:\x01<12}'.format(3+2.0j), '(3+2j)\x01\x01\x01\x01\x01\x01')
self.assertEqual('{0:\x00^12}'.format(3+2.0j), '\x00\x00\x00(3+2j)\x00\x00\x00')
self.assertEqual('{0:^12}'.format(3+2.0j), ' (3+2j) ')
# format specifiers for user defined type # format specifiers for user defined type
self.assertEqual(u'{0:abc}'.format(C()), u'abc') self.assertEqual(u'{0:abc}'.format(C()), u'abc')
......
...@@ -40,6 +40,9 @@ Core and Builtins ...@@ -40,6 +40,9 @@ Core and Builtins
- Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2 - Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2
billion characters) input strings in _Py_dg_strtod. billion characters) input strings in _Py_dg_strtod.
- Issue #12546: Allow \x00 to be used as a fill character when using str, int,
float, and complex __format__ methods.
Library Library
------- -------
......
...@@ -180,8 +180,9 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, ...@@ -180,8 +180,9 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
Py_ssize_t consumed; Py_ssize_t consumed;
int align_specified = 0; int align_specified = 0;
int fill_char_specified = 0;
format->fill_char = '\0'; format->fill_char = ' ';
format->align = default_align; format->align = default_align;
format->alternate = 0; format->alternate = 0;
format->sign = '\0'; format->sign = '\0';
...@@ -195,6 +196,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, ...@@ -195,6 +196,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
if (end-ptr >= 2 && is_alignment_token(ptr[1])) { if (end-ptr >= 2 && is_alignment_token(ptr[1])) {
format->align = ptr[1]; format->align = ptr[1];
format->fill_char = ptr[0]; format->fill_char = ptr[0];
fill_char_specified = 1;
align_specified = 1; align_specified = 1;
ptr += 2; ptr += 2;
} }
...@@ -218,7 +220,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec, ...@@ -218,7 +220,7 @@ parse_internal_render_format_spec(STRINGLIB_CHAR *format_spec,
} }
/* The special case for 0-padding (backwards compat) */ /* The special case for 0-padding (backwards compat) */
if (format->fill_char == '\0' && end-ptr >= 1 && ptr[0] == '0') { if (!fill_char_specified && end-ptr >= 1 && ptr[0] == '0') {
format->fill_char = '0'; format->fill_char = '0';
if (!align_specified) { if (!align_specified) {
format->align = '='; format->align = '=';
...@@ -715,8 +717,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format) ...@@ -715,8 +717,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format)
/* Write into that space. First the padding. */ /* Write into that space. First the padding. */
p = fill_padding(STRINGLIB_STR(result), len, p = fill_padding(STRINGLIB_STR(result), len,
format->fill_char=='\0'?' ':format->fill_char, format->fill_char, lpad, rpad);
lpad, rpad);
/* Then the source string. */ /* Then the source string. */
memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR)); memcpy(p, STRINGLIB_STR(value), len * sizeof(STRINGLIB_CHAR));
...@@ -893,8 +894,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format, ...@@ -893,8 +894,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
/* Populate the memory. */ /* Populate the memory. */
fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits, fill_number(STRINGLIB_STR(result), &spec, pnumeric_chars, n_digits,
prefix, format->fill_char == '\0' ? ' ' : format->fill_char, prefix, format->fill_char, &locale, format->type == 'X');
&locale, format->type == 'X');
done: done:
Py_XDECREF(tmp); Py_XDECREF(tmp);
...@@ -1048,8 +1048,7 @@ format_float_internal(PyObject *value, ...@@ -1048,8 +1048,7 @@ format_float_internal(PyObject *value,
/* Populate the memory. */ /* Populate the memory. */
fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL, fill_number(STRINGLIB_STR(result), &spec, p, n_digits, NULL,
format->fill_char == '\0' ? ' ' : format->fill_char, &locale, format->fill_char, &locale, 0);
0);
done: done:
PyMem_Free(buf); PyMem_Free(buf);
...@@ -1265,8 +1264,7 @@ format_complex_internal(PyObject *value, ...@@ -1265,8 +1264,7 @@ format_complex_internal(PyObject *value,
/* Populate the memory. First, the padding. */ /* Populate the memory. First, the padding. */
p = fill_padding(STRINGLIB_STR(result), p = fill_padding(STRINGLIB_STR(result),
n_re_total + n_im_total + 1 + add_parens * 2, n_re_total + n_im_total + 1 + add_parens * 2,
format->fill_char=='\0' ? ' ' : format->fill_char, format->fill_char, lpad, rpad);
lpad, rpad);
if (add_parens) if (add_parens)
*p++ = '('; *p++ = '(';
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment