mirror of https://github.com/python/cpython
Fix "%f" format of str%args if the result is not an ASCII or latin1 string
This commit is contained in:
parent
9a77770add
commit
184252ad3f
|
@ -265,6 +265,8 @@ class FormatTest(unittest.TestCase):
|
||||||
raise TestFailed('"%*d"%(maxsize, -127) should fail')
|
raise TestFailed('"%*d"%(maxsize, -127) should fail')
|
||||||
|
|
||||||
def test_non_ascii(self):
|
def test_non_ascii(self):
|
||||||
|
testformat("\u20ac=%f", (1.0,), "\u20ac=1.000000")
|
||||||
|
|
||||||
self.assertEqual(format("abc", "\u2007<5"), "abc\u2007\u2007")
|
self.assertEqual(format("abc", "\u2007<5"), "abc\u2007\u2007")
|
||||||
self.assertEqual(format(123, "\u2007<5"), "123\u2007\u2007")
|
self.assertEqual(format(123, "\u2007<5"), "123\u2007\u2007")
|
||||||
self.assertEqual(format(12.3, "\u2007<6"), "12.3\u2007\u2007")
|
self.assertEqual(format(12.3, "\u2007<6"), "12.3\u2007\u2007")
|
||||||
|
|
|
@ -1660,34 +1660,34 @@ unicode_putchar(PyObject **p_unicode, Py_ssize_t *pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy a ASCII or latin1 char* string into a Python Unicode string.
|
/* Copy a ASCII or latin1 char* string into a Python Unicode string.
|
||||||
Return the length of the input string.
|
|
||||||
|
|
||||||
WARNING: The function doesn't copy the terminating null character and
|
WARNING: The function doesn't copy the terminating null character and
|
||||||
doesn't check the maximum character (may write a latin1 character in an
|
doesn't check the maximum character (may write a latin1 character in an
|
||||||
ASCII string). */
|
ASCII string). */
|
||||||
static Py_ssize_t
|
static void
|
||||||
unicode_write_cstr(PyObject *unicode, Py_ssize_t index, const char *str)
|
unicode_write_cstr(PyObject *unicode, Py_ssize_t index,
|
||||||
|
const char *str, Py_ssize_t len)
|
||||||
{
|
{
|
||||||
enum PyUnicode_Kind kind = PyUnicode_KIND(unicode);
|
enum PyUnicode_Kind kind = PyUnicode_KIND(unicode);
|
||||||
void *data = PyUnicode_DATA(unicode);
|
void *data = PyUnicode_DATA(unicode);
|
||||||
|
const char *end = str + len;
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case PyUnicode_1BYTE_KIND: {
|
case PyUnicode_1BYTE_KIND: {
|
||||||
Py_ssize_t len = strlen(str);
|
|
||||||
assert(index + len <= PyUnicode_GET_LENGTH(unicode));
|
assert(index + len <= PyUnicode_GET_LENGTH(unicode));
|
||||||
memcpy((char *) data + index, str, len);
|
memcpy((char *) data + index, str, len);
|
||||||
return len;
|
break;
|
||||||
}
|
}
|
||||||
case PyUnicode_2BYTE_KIND: {
|
case PyUnicode_2BYTE_KIND: {
|
||||||
Py_UCS2 *start = (Py_UCS2 *)data + index;
|
Py_UCS2 *start = (Py_UCS2 *)data + index;
|
||||||
Py_UCS2 *ucs2 = start;
|
Py_UCS2 *ucs2 = start;
|
||||||
assert(index <= PyUnicode_GET_LENGTH(unicode));
|
assert(index <= PyUnicode_GET_LENGTH(unicode));
|
||||||
|
|
||||||
for (; *str; ++ucs2, ++str)
|
for (; str < end; ++ucs2, ++str)
|
||||||
*ucs2 = (Py_UCS2)*str;
|
*ucs2 = (Py_UCS2)*str;
|
||||||
|
|
||||||
assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
|
assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
|
||||||
return ucs2 - start;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
Py_UCS4 *start = (Py_UCS4 *)data + index;
|
Py_UCS4 *start = (Py_UCS4 *)data + index;
|
||||||
|
@ -1695,11 +1695,10 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, const char *str)
|
||||||
assert(kind == PyUnicode_4BYTE_KIND);
|
assert(kind == PyUnicode_4BYTE_KIND);
|
||||||
assert(index <= PyUnicode_GET_LENGTH(unicode));
|
assert(index <= PyUnicode_GET_LENGTH(unicode));
|
||||||
|
|
||||||
for (; *str; ++ucs4, ++str)
|
for (; str < end; ++ucs4, ++str)
|
||||||
*ucs4 = (Py_UCS4)*str;
|
*ucs4 = (Py_UCS4)*str;
|
||||||
|
|
||||||
assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
|
assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
|
||||||
return ucs4 - start;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2730,17 +2729,18 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'p':
|
case 'p':
|
||||||
{
|
{
|
||||||
Py_ssize_t written;
|
Py_ssize_t len;
|
||||||
/* unused, since we already have the result */
|
/* unused, since we already have the result */
|
||||||
if (*f == 'p')
|
if (*f == 'p')
|
||||||
(void) va_arg(vargs, void *);
|
(void) va_arg(vargs, void *);
|
||||||
else
|
else
|
||||||
(void) va_arg(vargs, int);
|
(void) va_arg(vargs, int);
|
||||||
/* extract the result from numberresults and append. */
|
/* extract the result from numberresults and append. */
|
||||||
written = unicode_write_cstr(string, i, numberresult);
|
len = strlen(numberresult);
|
||||||
|
unicode_write_cstr(string, i, numberresult, len);
|
||||||
/* skip over the separating '\0' */
|
/* skip over the separating '\0' */
|
||||||
i += written;
|
i += len;
|
||||||
numberresult += written;
|
numberresult += len;
|
||||||
assert(*numberresult == '\0');
|
assert(*numberresult == '\0');
|
||||||
numberresult++;
|
numberresult++;
|
||||||
assert(numberresult <= numberresults + numbersize);
|
assert(numberresult <= numberresults + numbersize);
|
||||||
|
@ -2812,10 +2812,14 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
|
||||||
PyUnicode_WRITE(kind, data, i++, '%');
|
PyUnicode_WRITE(kind, data, i++, '%');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
i += unicode_write_cstr(string, i, p);
|
{
|
||||||
|
Py_ssize_t len = strlen(p);
|
||||||
|
unicode_write_cstr(string, i, p, len);
|
||||||
|
i += len;
|
||||||
assert(i == PyUnicode_GET_LENGTH(string));
|
assert(i == PyUnicode_GET_LENGTH(string));
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(i < PyUnicode_GET_LENGTH(string));
|
assert(i < PyUnicode_GET_LENGTH(string));
|
||||||
|
@ -13211,9 +13215,7 @@ formatfloat(PyObject *v, int flags, int prec, int type,
|
||||||
if (writer) {
|
if (writer) {
|
||||||
if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1)
|
if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
memcpy((char*)writer->data + writer->pos * writer->kind,
|
unicode_write_cstr(writer->buffer, writer->pos, p, len);
|
||||||
p,
|
|
||||||
len);
|
|
||||||
writer->pos += len;
|
writer->pos += len;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue