diff --git a/parser/astgen/eval_literal.py b/parser/astgen/eval_literal.py index a2ae949..8d3b419 100644 --- a/parser/astgen/eval_literal.py +++ b/parser/astgen/eval_literal.py @@ -64,13 +64,12 @@ def _handle_hex_escape(self, length, i, start_i): raise self.err( f"Unterminated escape in string (expected {length}" f" hex digits)", StrRegion(start_i, i)) - try: - value = int(digits, base=16) - except ValueError: + if set(digits) - _HEX_DIGITS: # Just report entire escape as error region raise self.err( f"Invalid escape in string (expected {length} hex digits)", - StrRegion(start_i, i)) from None + StrRegion(start_i, i)) + value = int(digits, base=16) # Should never be error here (only hex digits here) return chr(value), i # the Very Special Case: \N{......} @@ -129,3 +128,4 @@ def err(self, msg: str, subregion: StrRegion): 'u': 4, # \uHHHH 'U': 8, # \Uhhhhhhhh } +_HEX_DIGITS = set('0123456789abcdef') diff --git a/test/coverage/inject_me.js b/test/coverage/inject_me.js index 5d22260..b810848 100644 --- a/test/coverage/inject_me.js +++ b/test/coverage/inject_me.js @@ -36,9 +36,28 @@ function linkifyRow(tr) { function linkifyAll() { document.querySelectorAll('tr.region').forEach(linkifyRow); } +const PREVENT_FILTER_TOTAL = true; +function preventUpdateTotalCell(cell) { + let target = cell.classList; + let oldContains = target.contains.bind(target); + function newContains(value) { + // Tell the Coverage.py code that all entries in total row are 'name' + // so it doesn't try to modify them. + if (value == "name") return true; + return oldContains(value); + } + target.contains = newContains; +} +function preventUpdateTotal() { + [...document.querySelector('table.index').tFoot.rows[0].cells] + .forEach(preventUpdateTotalCell); +} addEventListener('load', () => { if(document.body.classList.contains("indexfile")) { setColors(); linkifyAll(); + if(PREVENT_FILTER_TOTAL) { + preventUpdateTotal(); + } } }); diff --git a/test/test_eval_literal.py b/test/test_eval_literal.py index 625e6a4..5ff0d25 100644 --- a/test/test_eval_literal.py +++ b/test/test_eval_literal.py @@ -69,6 +69,13 @@ def test_error(self): r'tests would break}"', StrRegion(3, 3 + 73)) self.assertContains(msg.lower(), "unknown unicode character name") + def test_bad_hex_escape_2(self): + msg = self._assert_err_and_region(r'"\x-9"', StrRegion(3, 7)) + self.assertContains(msg, "expected 2") + + msg = self._assert_err_and_region(r'"\u 4fe1"', StrRegion(3, 9)) + self.assertContains(msg, "expected 4") + def test_py_consistency(self): base = r'a\\\a\b\v\f\0\n\rq\t' '\\"' "\\'" for x in (*range(0, 34, 3), *range(34, 256, 9), 255):