From d2b58a9880d119b20e1fc1c82a3e2e2d9eaa0817 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Fri, 17 May 2013 17:34:30 -0500 Subject: [PATCH] only recursively expand in the format spec (closes #17644) --- Lib/test/test_unicode.py | 2 ++ Misc/NEWS | 3 +++ Objects/stringlib/unicode_format.h | 10 ++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index d4e2222fa92..bef64aa7ccb 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -934,6 +934,8 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual("{0:.0s}".format("ABC\u0410\u0411\u0412"), '') + self.assertEqual("{[{}]}".format({"{}": 5}), "5") + def test_format_map(self): self.assertEqual(''.format_map({}), '') self.assertEqual('a'.format_map({}), 'a') diff --git a/Misc/NEWS b/Misc/NEWS index 251804dd526..14be9391d35 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 3.3.3 release candidate 1? Core and Builtins ----------------- +- Issue #17644: Fix a crash in str.format when curly braces are used in square + brackets. + - Issue #17983: Raise a SyntaxError for a ``global __class__`` statement in a class body. diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index e9be516318f..c1c2cf37812 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -638,7 +638,7 @@ MarkupIterator_next(MarkupIterator *self, SubString *literal, SubString *format_spec, Py_UCS4 *conversion, int *format_spec_needs_expanding) { - int at_end; + int at_end, hit_format_spec; Py_UCS4 c = 0; Py_ssize_t start; int count; @@ -723,12 +723,18 @@ MarkupIterator_next(MarkupIterator *self, SubString *literal, /* we know we can't have a zero length string, so don't worry about that case */ + hit_format_spec = 0; while (self->str.start < self->str.end) { switch (c = PyUnicode_READ_CHAR(self->str.str, self->str.start++)) { + case ':': + hit_format_spec = 1; + count = 1; + break; case '{': /* the format spec needs to be recursively expanded. this is an optimization, and not strictly needed */ - *format_spec_needs_expanding = 1; + if (hit_format_spec) + *format_spec_needs_expanding = 1; count++; break; case '}':