Skip to content

gh-97556: Fix crash on null characters in string literal parser - #97577

Open
apccurtiss wants to merge 6 commits into
python:mainfrom
apccurtiss:fix-issue-97556
Open

apccurtiss wants to merge 6 commits into
python:mainfrom
apccurtiss:fix-issue-97556

Conversation

@apccurtiss

@apccurtiss apccurtiss commented Sep 26, 2022 •

Copy link
Copy Markdown

The _PyPegen_parsestr function was crashing on null characters inside of string literals due to a call to strlen, which treated it as a null terminator.

This change removes that call, which was actually redundant: the length was already calculated by the caller function and can be retrieved using PyBytes_AsStringAndSize. This has the added benefit of reducing the number of times the length gets calculated.

@bedevere-bot

Copy link
Copy Markdown

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@ghost

ghost commented Sep 26, 2022 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.
CLA signed

@bedevere-bot

Copy link
Copy Markdown

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@gvanrossum gvanrossum changed the title gh-96670: String literal parser no longer crashes on null characters gh-96670: Fix crash on null characters in string literal parser Sep 26, 2022

@gvanrossum gvanrossum left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good catch, and the patch is almost perfect (I have one minor suggestion).

Could you also add a unittest that demonstrates the bug?

Comment thread Parser/string_parser.c Outdated
Comment on lines 229 to 231
if (len > INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "string to parse is too long");
return -1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this check to the top? I really don't care about the case where the string including quotes is just over INT_MAX but after stripping quotes it fits.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. Also, I just realized I copied the wrong issue number in the title (I meant #97556): is it enough to change the title, or should I create a whole new pull request?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just edit the title.

@apccurtiss apccurtiss changed the title gh-96670: Fix crash on null characters in string literal parser gh-97556: Fix crash on null characters in string literal parser Sep 26, 2022
@apccurtiss

Copy link
Copy Markdown
Author

I'm having trouble including a unit test due to a similar issue, #96670. Null characters raise errors when they are included in source code that is parsed using ast.parse, or which is imported from another file. So I have a test case for this which can be run directly, but it cannot be imported as part of the standard test suite. Any suggestions on how to work around that?

@gvanrossum

Copy link
Copy Markdown
Member

I'm having trouble including a unit test due to a similar issue, #96670. Null characters raise errors when they are included in source code that is parsed using ast.parse, or which is imported from another file. So I have a test case for this which can be run directly, but it cannot be imported as part of the standard test suite. Any suggestions on how to work around that?

You can write the test program to a file with a .py extension, manipulate sys.path so you can import that file, and attempt to import it. I think there are a few other tests that do that. E.g. look in test_bdb.py for import_helper.

@pablogsal

Copy link
Copy Markdown
Member

You can write the test program to a file with a .py extension, manipulate sys.path so you can import that file, and attempt to import it. I think there are a few other tests that do that. E.g. look in test_bdb.py for import_helper.

An easier way is to write the test code as a string and use the support.assert_python_ok helper to execute the test code. Check this as an example:

def test_basic_script(self):
with os_helper.temp_dir() as script_dir:
script_name = _make_test_script(script_dir, 'script')
self._check_script(script_name, script_name, script_name,
script_dir, None,
importlib.machinery.SourceFileLoader,
expected_cwd=script_dir)

@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Apr 11, 2026

@pablogsal pablogsal left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some small comments

Comment thread Parser/string_parser.c
char *s;
Py_ssize_t len;

if (PyBytes_AsStringAndSize(t->bytes, &s, &len)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we reject this in the tokenizer instead? Otherwise files with NUL bytes in a string literal become valid source, while compile() still rejects NUL bytes.

Comment thread Parser/string_parser.c
char *s;
Py_ssize_t len;

if (PyBytes_AsStringAndSize(t->bytes, &s, &len)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a crash fix but it lands without a regression test. I know a .py file with a null byte is blocked by gh-96670, but can we still add a regression test somehow, e.g. compiling a bytes source with an embedded null? We really want to keep this from regressing.

@@ -0,0 +1 @@
Fix interpreter crash when a string literal contains a null character.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this NEWS entry is filed under gh-issue-96670, but this PR fixes gh-97556. Can we rename it so the changelog points to the right issue?

@github-actions github-actions Bot removed the stale Stale PR or inactive for long period of time. label Jul 1, 2026
@github-actions

Copy link
Copy Markdown

This PR is stale because it has been open for 90 days with no activity.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review stale Stale PR or inactive for long period of time.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants