Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Report the offending char, not the backslash, for invalid \X escapes - #380

Merged
etrepum merged 1 commit into
simplejson:mainfrom
binggao1230:fix-c-scanstring-esc1-position
Jul 6, 2026
Merged

etrepum merged 1 commit into
simplejson:mainfrom
binggao1230:fix-c-scanstring-esc1-position

Conversation

@binggao1230

Copy link
Copy Markdown
Contributor

Problem

For an invalid single-character escape (\X), the C scanstring reports the
position of the backslash and renders the wrong character in the message,
while the pure-Python py_scanstring reports the offending escape character:

>>> import simplejson
>>> simplejson.loads('"\\x41"')
# C path:      Invalid \X escape sequence '\' : line 1 column 1 (char 0)
# Python path: Invalid \X escape sequence 'x' : line 1 column 2 (char 1)

ERR_STRING_ESC1 renders %r of the character at the reported position, so
passing end - 2 names '\' — the backslash, which is always a valid escape
introducer — and points at the wrong column. This is actively misleading when
debugging malformed JSON through the C-accelerated path.

Cause

simplejson/_speedups.c passes end - 2 (the backslash) instead of end - 1
(the escape character) to raise_errmsg(state, ERR_STRING_ESC1, ...) in all
three scanstring branches (scanstring_str and both scanstring_unicode
includes).

Fix

Pass end - 1 in the three branches so the C extension names the actual
offending character and reports the same position as the pure-Python reference.
This mirrors the control-character position fix in #379.

Tests

test_single_char_escape_error_parity asserts exact (position, message)
parity between c_scanstring and py_scanstring across five invalid-escape
inputs, and that the reported position never lands on the backslash. It mirrors
the existing test_escape_error_parity (which covers the \uXXXX branch).

Full test suite (C-speedups path and pure-Python path): 190 passed, 30 skipped,
0 regressions.

For an invalid single-character escape, the C scanstring passed end - 2 (the
backslash) to raise_errmsg for ERR_STRING_ESC1, while py_scanstring reports
end - 1 (the escape character). Since ERR_STRING_ESC1 renders %r of the
character at the reported position, the C path produced the nonsensical
"Invalid \\X escape sequence '\\'" - naming the backslash, which is always a
valid escape introducer - and pointed at the wrong column.

Pass end - 1 in all three scanstring branches so the C extension names the
actual offending character and reports the same position as the pure-Python
reference. This mirrors the control-character position fix in simplejson#379.
@etrepum
etrepum added this pull request to the merge queue Jul 6, 2026
Merged via the queue into simplejson:main with commit fa8feea Jul 6, 2026
26 checks passed
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Aug 28, 2026
Version 4.1.2 released 2026-08-26

* Fix control character error position when content precedes the control char
  simplejson/simplejson#379
* Report the offending char, not the backslash, for invalid \X escapes
  simplejson/simplejson#380
* Handle non-finite Decimals like floats in the encoder
  simplejson/simplejson#381
* Parse failures due to trailing commas are now reported consistently
  across implementations
  simplejson/simplejson#382
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants