Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-41060: Avoid SEGFAULT when calling GET_INVALID_TARGET in the grammar #21020

Merged
merged 3 commits into from
Jun 21, 2020

Conversation

lysnikolaou
Copy link
Contributor

@lysnikolaou lysnikolaou commented Jun 20, 2020

GET_INVALID_TARGET might unexpectedly return NULL, which if not
caught will cause a SEGFAULT. Therefore, this PR introduces a new
inline function RAISE_SYNTAX_ERROR_INVALID_TARGET that always
checks for GET_INVALID_TARGET returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.

https://bugs.python.org/issue41060

`GET_INVALID_TARGET` might unexpectedly return `NULL`, which if not
caught will cause a SEGFAULT. Therefore, this PR introduces a new
inline function `RAISE_SYNTAX_ERROR_INVALID_TARGET` that always
checks for `GET_INVALID_TARGET` returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.
@pablogsal
Copy link
Member

Seems that there is something missing still:

test_assign_call (test.test_syntax.SyntaxTestCase) ... ok
test_assign_del (test.test_syntax.SyntaxTestCase) ... python: Parser/pegen.h:164: CHECK_CALL: Assertion `PyErr_Occurred()' failed.
Fatal Python error: Aborted

@pablogsal
Copy link
Member

I have to say that I am a bit scared about how we are dealing with this part, it seems that is super easy to forget some combination that segfaults :(

@lysnikolaou
Copy link
Contributor Author

I have to say that I am a bit scared about how we are dealing with this part, it seems that is super easy to forget some combination that segfaults :(

I agree that this approach makes it fairly easy to miss corner cases. Still, I'm having a hard time figuring out what other approaches we could think of that don't.

@pablogsal
Copy link
Member

I agree that this approach makes it fairly easy to miss corner cases. Still, I'm having a hard time figuring out what other approaches we could think of that don't.

A lot of the time the problem is that we pass NULL to PyPegen_get_expr_name so maybe we should add code to this function that returns something generic so the we do not crash (maybe something that makes the error generic like 'Cannot assign to invalid target').

@lysnikolaou
Copy link
Contributor Author

lysnikolaou commented Jun 21, 2020

I agree that this approach makes it fairly easy to miss corner cases. Still, I'm having a hard time figuring out what other approaches we could think of that don't.

A lot of the time the problem is that we pass NULL to PyPegen_get_expr_name so maybe we should add code to this function that returns something generic so the we do not crash (maybe something that makes the error generic like 'Cannot assign to invalid target').

That is what this PR does, no? The return value of GET_INVALID_TARGET gets checked, before passing it to _PyPegen_get_expr_name. If it's NULL, RAISE_SYNTAX_ERROR("invalid_syntax") gets called instead.

@@ -199,6 +199,10 @@
Traceback (most recent call last):
SyntaxError: invalid syntax

>>> for a, b
Copy link
Member

Choose a reason for hiding this comment

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

If we backport this PR, are these compatible with the old parser?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup yup, they should be.

@pablogsal
Copy link
Member

That is what this PR does, no? The return value of GET_INVALID_TARGET gets checked, before passing it to _PyPegen_get_expr_name. If it's NULL, RAISE_SYNTAX_ERROR("invalid_syntax") gets called instead.

Yep yep, I wrote that before checking 😅 What I had in mind is some in-between message not that generic as invalid syntax but a bit more specialized ("Cannot assign/delete invalid target" or something like that). But I am fine with invalid syntax though.

@lysnikolaou
Copy link
Contributor Author

lysnikolaou commented Jun 21, 2020

"Cannot assign/delete invalid target" or something like that

This error message would be misleading in some cases though. For the input with a as b for example, the target is fine. It is the missing colon afterwards that's wrong.

@pablogsal pablogsal added the needs backport to 3.9 only security fixes label Jun 21, 2020
@pablogsal pablogsal merged commit 6c4e0bd into python:master Jun 21, 2020
@miss-islington
Copy link
Contributor

Thanks @lysnikolaou for the PR, and @pablogsal for merging it 🌮🎉.. I'm working now to backport this PR to: 3.9.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @lysnikolaou and @pablogsal, I could not cleanly backport this to 3.9 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 6c4e0bd974f2895d42b63d9d004587e74b286c88 3.9

@pablogsal
Copy link
Member

Seems that we need to do a manual backport

@lysnikolaou lysnikolaou deleted the targets-fix branch June 21, 2020 02:22
@lysnikolaou
Copy link
Contributor Author

Seems that we need to do a manual backport

No worries, I'll do it.

lysnikolaou added a commit to lysnikolaou/cpython that referenced this pull request Jun 21, 2020
…mar (pythonGH-21020)

`GET_INVALID_TARGET` might unexpectedly return `NULL`, which if not
caught will cause a SEGFAULT. Therefore, this commit introduces a new
inline function `RAISE_SYNTAX_ERROR_INVALID_TARGET` that always
checks for `GET_INVALID_TARGET` returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.

(cherry picked from commit 6c4e0bd)
@bedevere-bot bedevere-bot removed the needs backport to 3.9 only security fixes label Jun 21, 2020
@bedevere-bot
Copy link

GH-21024 is a backport of this pull request to the 3.9 branch.

miss-islington pushed a commit that referenced this pull request Jun 21, 2020
…e grammar (GH-21020) (GH-21024)

`GET_INVALID_TARGET` might unexpectedly return `NULL`, which if not
caught will cause a SEGFAULT. Therefore, this commit introduces a new
inline function `RAISE_SYNTAX_ERROR_INVALID_TARGET` that always
checks for `GET_INVALID_TARGET` returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.

(cherry picked from commit 6c4e0bd)

Automerge-Triggered-By: @pablogsal
fasih pushed a commit to fasih/cpython that referenced this pull request Jun 29, 2020
…mar (pythonGH-21020)

`GET_INVALID_TARGET` might unexpectedly return `NULL`, which if not
caught will cause a SEGFAULT. Therefore, this commit introduces a new
inline function `RAISE_SYNTAX_ERROR_INVALID_TARGET` that always
checks for `GET_INVALID_TARGET` returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.
arun-mani-j pushed a commit to arun-mani-j/cpython that referenced this pull request Jul 21, 2020
…mar (pythonGH-21020)

`GET_INVALID_TARGET` might unexpectedly return `NULL`, which if not
caught will cause a SEGFAULT. Therefore, this commit introduces a new
inline function `RAISE_SYNTAX_ERROR_INVALID_TARGET` that always
checks for `GET_INVALID_TARGET` returning NULL and can be used in
the grammar, replacing the long C ternary operation used till now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants