summaryrefslogtreecommitdiffstats
path: root/Parser/pegen.h
diff options
context:
space:
mode:
authorLysandros Nikolaou <lisandrosnik@gmail.com>2020-06-21 02:18:01 (GMT)
committerGitHub <noreply@github.com>2020-06-21 02:18:01 (GMT)
commit6c4e0bd974f2895d42b63d9d004587e74b286c88 (patch)
tree68e8df81c6375ba0e85e614f6afd92d867a901af /Parser/pegen.h
parent3ccb96c9782480e5ce646a4a130569fb92f2965d (diff)
downloadcpython-6c4e0bd974f2895d42b63d9d004587e74b286c88.zip
cpython-6c4e0bd974f2895d42b63d9d004587e74b286c88.tar.gz
cpython-6c4e0bd974f2895d42b63d9d004587e74b286c88.tar.bz2
bpo-41060: Avoid SEGFAULT when calling GET_INVALID_TARGET in the grammar (GH-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.
Diffstat (limited to 'Parser/pegen.h')
-rw-r--r--Parser/pegen.h25
1 files changed, 22 insertions, 3 deletions
diff --git a/Parser/pegen.h b/Parser/pegen.h
index ef095dd..f407709 100644
--- a/Parser/pegen.h
+++ b/Parser/pegen.h
@@ -269,9 +269,28 @@ typedef enum {
FOR_TARGETS
} TARGETS_TYPE;
expr_ty _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type);
-#define GET_INVALID_TARGET(e) (expr_ty)CHECK(_PyPegen_get_invalid_target(e, STAR_TARGETS))
-#define GET_INVALID_DEL_TARGET(e) (expr_ty)CHECK_NULL_ALLOWED(_PyPegen_get_invalid_target(e, DEL_TARGETS))
-#define GET_INVALID_FOR_TARGET(e) (expr_ty)CHECK_NULL_ALLOWED(_PyPegen_get_invalid_target(e, FOR_TARGETS))
+#define RAISE_SYNTAX_ERROR_INVALID_TARGET(type, e) _RAISE_SYNTAX_ERROR_INVALID_TARGET(p, type, e)
+
+Py_LOCAL_INLINE(void *)
+_RAISE_SYNTAX_ERROR_INVALID_TARGET(Parser *p, TARGETS_TYPE type, void *e)
+{
+ expr_ty invalid_target = CHECK_NULL_ALLOWED(_PyPegen_get_invalid_target(e, type));
+ if (invalid_target != NULL) {
+ const char *msg;
+ if (type == STAR_TARGETS || type == FOR_TARGETS) {
+ msg = "cannot assign to %s";
+ }
+ else {
+ msg = "cannot delete %s";
+ }
+ return RAISE_SYNTAX_ERROR_KNOWN_LOCATION(
+ invalid_target,
+ msg,
+ _PyPegen_get_expr_name(invalid_target)
+ );
+ }
+ return RAISE_SYNTAX_ERROR("invalid syntax");
+}
void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
void *_PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args);