[pypy-commit] pypy py3.7: way too much work: forbid "% %" % () and variants
cfbolz
pypy.commits at gmail.com
Wed Jan 29 15:47:24 EST 2020
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.7
Changeset: r98598:a512d2966a9a
Date: 2020-01-29 21:46 +0100
http://bitbucket.org/pypy/pypy/changeset/a512d2966a9a/
Log: way too much work: forbid "% %" % () and variants
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -297,12 +297,20 @@
result.append_slice(fmt, i0, i)
self.fmtpos = i + 1
+ c = self.peekchr()
+ if c == '%':
+ self.forward()
+ self.result.append('%')
+ continue
+
# interpret the next formatter
w_value = self.parse_fmt()
c = self.peekchr()
self.forward()
if c == '%':
- self.result.append('%')
+ # if we get here there were extra characters between the
+ # two %, forbidden now
+ self.two_percent_error(i + 1)
continue
# first check whether it's a invalid char, *then* call
@@ -329,17 +337,29 @@
self.checkconsumed()
return result.build()
- def unknown_fmtchar(self):
+ def _get_error_info(self, pos):
space = self.space
if do_unicode:
- cp = rutf8.codepoint_at_pos(self.fmt, self.fmtpos - 1)
- pos = rutf8.codepoints_in_utf8(self.fmt, 0, self.fmtpos - 1)
+ cp = rutf8.codepoint_at_pos(self.fmt, pos)
+ pos = rutf8.codepoints_in_utf8(self.fmt, 0, pos)
w_s = space.newutf8(rutf8.unichr_as_utf8(r_uint(cp),
allow_surrogates=True), 1)
else:
- cp = ord(self.fmt[self.fmtpos - 1])
- pos = self.fmtpos - 1
+ cp = ord(self.fmt[pos])
w_s = space.newbytes(chr(cp))
+ return w_s, pos, cp
+
+ def two_percent_error(self, pos):
+ space = self.space
+ w_s, pos, cp = self._get_error_info(pos)
+ raise oefmt(space.w_ValueError,
+ # hahahaha
+ "extra character %R (%s) before escaped '%%' at index %d, use '%%%%'",
+ w_s, hex(cp), pos)
+
+ def unknown_fmtchar(self):
+ space = self.space
+ w_s, pos, cp = self._get_error_info(self.fmtpos - 1)
raise oefmt(space.w_ValueError,
"unsupported format character %R (%s) at index %d",
w_s, hex(cp), pos)
diff --git a/pypy/objspace/std/test/test_stringformat.py b/pypy/objspace/std/test/test_stringformat.py
--- a/pypy/objspace/std/test/test_stringformat.py
+++ b/pypy/objspace/std/test/test_stringformat.py
@@ -278,6 +278,11 @@
with raises(ValueError):
"%?" % {} # not TypeError
+ def test_no_chars_between_percent(self):
+ with raises(ValueError) as exc:
+ "% %" % ()
+ assert "extra character ' ' (0x20) before escaped '%' at index 1" in str(exc.value)
+
class AppTestWidthPrec:
def test_width(self):
a = 'a'
More information about the pypy-commit
mailing list