blob: 0a306c0b0579deec1634b6895c7109e77aced796 [file] [log] [blame]
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00001/*
Batuhan Taskaya02a16032020-10-10 20:14:59 +03002 * This file exposes PyAST_Validate interface to check the integrity
3 * of the given abstract syntax tree (potentially constructed manually).
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00004 */
5#include "Python.h"
Victor Stinner94faa072021-03-23 20:47:40 +01006#include "pycore_ast.h" // asdl_stmt_seq
Serhiy Storchakaface87c2021-04-25 13:38:00 +03007#include "pycore_pystate.h" // _PyThreadState_GET()
Jeremy Hylton3e0055f2005-10-20 19:59:25 +00008
9#include <assert.h>
Nick Coghlan1e7b8582021-04-29 15:58:44 +100010#include <stdbool.h>
Serhiy Storchaka58159ef2019-01-12 09:46:50 +020011
Serhiy Storchakaface87c2021-04-25 13:38:00 +030012struct validator {
13 int recursion_depth; /* current recursion depth */
14 int recursion_limit; /* recursion limit */
15};
16
17static int validate_stmts(struct validator *, asdl_stmt_seq *);
Batuhan Taskaya2f763682021-07-10 03:16:15 +030018static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
19static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
Pablo Galindoa5634c42020-09-16 19:42:00 +010020static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030021static int validate_stmt(struct validator *, stmt_ty);
22static int validate_expr(struct validator *, expr_ty, expr_context_ty);
Nick Coghlan1e7b8582021-04-29 15:58:44 +100023static int validate_pattern(struct validator *, pattern_ty);
Benjamin Peterson832bfe22011-08-09 16:15:04 -050024
25static int
Batuhan Taskaya68874a82020-06-06 15:44:16 +030026validate_name(PyObject *name)
27{
28 assert(PyUnicode_Check(name));
29 static const char * const forbidden[] = {
30 "None",
31 "True",
32 "False",
33 NULL
34 };
35 for (int i = 0; forbidden[i] != NULL; i++) {
36 if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
Batuhan Taskaya2f763682021-07-10 03:16:15 +030037 PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]);
Batuhan Taskaya68874a82020-06-06 15:44:16 +030038 return 0;
39 }
40 }
41 return 1;
42}
43
44static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030045validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050046{
Victor Stinner4d73ae72018-11-22 14:45:16 +010047 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050048 if (!asdl_seq_LEN(gens)) {
49 PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
50 return 0;
51 }
52 for (i = 0; i < asdl_seq_LEN(gens); i++) {
53 comprehension_ty comp = asdl_seq_GET(gens, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030054 if (!validate_expr(state, comp->target, Store) ||
55 !validate_expr(state, comp->iter, Load) ||
56 !validate_exprs(state, comp->ifs, Load, 0))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050057 return 0;
58 }
59 return 1;
60}
61
62static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030063validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050064{
Victor Stinner4d73ae72018-11-22 14:45:16 +010065 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050066 for (i = 0; i < asdl_seq_LEN(keywords); i++)
Serhiy Storchakaface87c2021-04-25 13:38:00 +030067 if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050068 return 0;
69 return 1;
70}
71
72static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030073validate_args(struct validator *state, asdl_arg_seq *args)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050074{
Victor Stinner4d73ae72018-11-22 14:45:16 +010075 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050076 for (i = 0; i < asdl_seq_LEN(args); i++) {
77 arg_ty arg = asdl_seq_GET(args, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030078 if (arg->annotation && !validate_expr(state, arg->annotation, Load))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050079 return 0;
80 }
81 return 1;
82}
83
84static const char *
85expr_context_name(expr_context_ty ctx)
86{
87 switch (ctx) {
88 case Load:
89 return "Load";
90 case Store:
91 return "Store";
92 case Del:
93 return "Del";
Nick Coghlan1e7b8582021-04-29 15:58:44 +100094 // No default case so compiler emits warning for unhandled cases
Benjamin Peterson832bfe22011-08-09 16:15:04 -050095 }
Nick Coghlan1e7b8582021-04-29 15:58:44 +100096 Py_UNREACHABLE();
Benjamin Peterson832bfe22011-08-09 16:15:04 -050097}
98
99static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300100validate_arguments(struct validator *state, arguments_ty args)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500101{
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300102 if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500103 return 0;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100104 }
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700105 if (args->vararg && args->vararg->annotation
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300106 && !validate_expr(state, args->vararg->annotation, Load)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500107 return 0;
108 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300109 if (!validate_args(state, args->kwonlyargs))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500110 return 0;
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100111 if (args->kwarg && args->kwarg->annotation
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300112 && !validate_expr(state, args->kwarg->annotation, Load)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500113 return 0;
114 }
Pablo Galindo2f58a842019-05-31 14:09:49 +0100115 if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500116 PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
117 return 0;
118 }
119 if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
120 PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
121 "kw_defaults on arguments");
122 return 0;
123 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300124 return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500125}
126
127static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300128validate_constant(struct validator *state, PyObject *value)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100129{
130 if (value == Py_None || value == Py_Ellipsis)
131 return 1;
132
133 if (PyLong_CheckExact(value)
134 || PyFloat_CheckExact(value)
135 || PyComplex_CheckExact(value)
136 || PyBool_Check(value)
137 || PyUnicode_CheckExact(value)
138 || PyBytes_CheckExact(value))
139 return 1;
140
141 if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300142 if (++state->recursion_depth > state->recursion_limit) {
143 PyErr_SetString(PyExc_RecursionError,
144 "maximum recursion depth exceeded during compilation");
145 return 0;
146 }
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100147
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300148 PyObject *it = PyObject_GetIter(value);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100149 if (it == NULL)
150 return 0;
151
152 while (1) {
153 PyObject *item = PyIter_Next(it);
154 if (item == NULL) {
155 if (PyErr_Occurred()) {
156 Py_DECREF(it);
157 return 0;
158 }
159 break;
160 }
161
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300162 if (!validate_constant(state, item)) {
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100163 Py_DECREF(it);
Victor Stinner726f6902016-01-27 00:11:47 +0100164 Py_DECREF(item);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100165 return 0;
166 }
Victor Stinner726f6902016-01-27 00:11:47 +0100167 Py_DECREF(item);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100168 }
169
170 Py_DECREF(it);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300171 --state->recursion_depth;
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100172 return 1;
173 }
174
Batuhan TaÅŸkaya0ac59f92020-03-19 14:32:28 +0300175 if (!PyErr_Occurred()) {
176 PyErr_Format(PyExc_TypeError,
177 "got an invalid type in Constant: %s",
178 _PyType_Name(Py_TYPE(value)));
179 }
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100180 return 0;
181}
182
183static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300184validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500185{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000186 int ret = -1;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300187 if (++state->recursion_depth > state->recursion_limit) {
188 PyErr_SetString(PyExc_RecursionError,
189 "maximum recursion depth exceeded during compilation");
190 return 0;
191 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500192 int check_ctx = 1;
193 expr_context_ty actual_ctx;
194
195 /* First check expression context. */
196 switch (exp->kind) {
197 case Attribute_kind:
198 actual_ctx = exp->v.Attribute.ctx;
199 break;
200 case Subscript_kind:
201 actual_ctx = exp->v.Subscript.ctx;
202 break;
203 case Starred_kind:
204 actual_ctx = exp->v.Starred.ctx;
205 break;
206 case Name_kind:
Batuhan Taskaya68874a82020-06-06 15:44:16 +0300207 if (!validate_name(exp->v.Name.id)) {
208 return 0;
209 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500210 actual_ctx = exp->v.Name.ctx;
211 break;
212 case List_kind:
213 actual_ctx = exp->v.List.ctx;
214 break;
215 case Tuple_kind:
216 actual_ctx = exp->v.Tuple.ctx;
217 break;
218 default:
219 if (ctx != Load) {
220 PyErr_Format(PyExc_ValueError, "expression which can't be "
221 "assigned to in %s context", expr_context_name(ctx));
222 return 0;
223 }
224 check_ctx = 0;
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100225 /* set actual_ctx to prevent gcc warning */
226 actual_ctx = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500227 }
228 if (check_ctx && actual_ctx != ctx) {
229 PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
230 expr_context_name(ctx), expr_context_name(actual_ctx));
231 return 0;
232 }
233
234 /* Now validate expression. */
235 switch (exp->kind) {
236 case BoolOp_kind:
237 if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
238 PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
239 return 0;
240 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300241 ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
242 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500243 case BinOp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300244 ret = validate_expr(state, exp->v.BinOp.left, Load) &&
245 validate_expr(state, exp->v.BinOp.right, Load);
246 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500247 case UnaryOp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300248 ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
249 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500250 case Lambda_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300251 ret = validate_arguments(state, exp->v.Lambda.args) &&
252 validate_expr(state, exp->v.Lambda.body, Load);
253 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500254 case IfExp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300255 ret = validate_expr(state, exp->v.IfExp.test, Load) &&
256 validate_expr(state, exp->v.IfExp.body, Load) &&
257 validate_expr(state, exp->v.IfExp.orelse, Load);
258 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500259 case Dict_kind:
260 if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
261 PyErr_SetString(PyExc_ValueError,
262 "Dict doesn't have the same number of keys as values");
263 return 0;
264 }
Yury Selivanovb3d53132015-09-01 16:10:49 -0400265 /* null_ok=1 for keys expressions to allow dict unpacking to work in
266 dict literals, i.e. ``{**{a:b}}`` */
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300267 ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
268 validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
269 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500270 case Set_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300271 ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
272 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500273#define COMP(NAME) \
274 case NAME ## _kind: \
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300275 ret = validate_comprehension(state, exp->v.NAME.generators) && \
276 validate_expr(state, exp->v.NAME.elt, Load); \
277 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500278 COMP(ListComp)
279 COMP(SetComp)
280 COMP(GeneratorExp)
281#undef COMP
282 case DictComp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300283 ret = validate_comprehension(state, exp->v.DictComp.generators) &&
284 validate_expr(state, exp->v.DictComp.key, Load) &&
285 validate_expr(state, exp->v.DictComp.value, Load);
286 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500287 case Yield_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300288 ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
289 break;
Benjamin Peterson527c6222012-01-14 08:58:23 -0500290 case YieldFrom_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300291 ret = validate_expr(state, exp->v.YieldFrom.value, Load);
292 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400293 case Await_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300294 ret = validate_expr(state, exp->v.Await.value, Load);
295 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500296 case Compare_kind:
297 if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
298 PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
299 return 0;
300 }
301 if (asdl_seq_LEN(exp->v.Compare.comparators) !=
302 asdl_seq_LEN(exp->v.Compare.ops)) {
303 PyErr_SetString(PyExc_ValueError, "Compare has a different number "
304 "of comparators and operands");
305 return 0;
306 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300307 ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
308 validate_expr(state, exp->v.Compare.left, Load);
309 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500310 case Call_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300311 ret = validate_expr(state, exp->v.Call.func, Load) &&
312 validate_exprs(state, exp->v.Call.args, Load, 0) &&
313 validate_keywords(state, exp->v.Call.keywords);
314 break;
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100315 case Constant_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300316 if (!validate_constant(state, exp->v.Constant.value)) {
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100317 return 0;
318 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300319 ret = 1;
320 break;
Eric V. Smith235a6f02015-09-19 14:51:32 -0400321 case JoinedStr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300322 ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
323 break;
Eric V. Smith235a6f02015-09-19 14:51:32 -0400324 case FormattedValue_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300325 if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
Eric V. Smith235a6f02015-09-19 14:51:32 -0400326 return 0;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300327 if (exp->v.FormattedValue.format_spec) {
328 ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
329 break;
330 }
331 ret = 1;
332 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500333 case Attribute_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300334 ret = validate_expr(state, exp->v.Attribute.value, Load);
335 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500336 case Subscript_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300337 ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
338 validate_expr(state, exp->v.Subscript.value, Load);
339 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500340 case Starred_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300341 ret = validate_expr(state, exp->v.Starred.value, ctx);
342 break;
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200343 case Slice_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300344 ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
345 (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
346 (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
347 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500348 case List_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300349 ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
350 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500351 case Tuple_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300352 ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
353 break;
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000354 case NamedExpr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300355 ret = validate_expr(state, exp->v.NamedExpr.value, Load);
356 break;
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300357 /* This last case doesn't have any checking. */
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500358 case Name_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300359 ret = 1;
360 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000361 // No default case so compiler emits warning for unhandled cases
362 }
363 if (ret < 0) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300364 PyErr_SetString(PyExc_SystemError, "unexpected expression");
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000365 ret = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500366 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300367 state->recursion_depth--;
368 return ret;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500369}
370
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000371
372// Note: the ensure_literal_* functions are only used to validate a restricted
373// set of non-recursive literals that have already been checked with
374// validate_expr, so they don't accept the validator state
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500375static int
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000376ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
Brandt Bucher145bf262021-02-26 14:51:55 -0800377{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000378 assert(exp->kind == Constant_kind);
379 PyObject *value = exp->v.Constant.value;
380 return (allow_real && PyFloat_CheckExact(value)) ||
381 (allow_real && PyLong_CheckExact(value)) ||
382 (allow_imaginary && PyComplex_CheckExact(value));
383}
384
385static int
386ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
387{
388 assert(exp->kind == UnaryOp_kind);
389 // Must be negation ...
390 if (exp->v.UnaryOp.op != USub) {
391 return 0;
392 }
393 // ... of a constant ...
394 expr_ty operand = exp->v.UnaryOp.operand;
395 if (operand->kind != Constant_kind) {
396 return 0;
397 }
398 // ... number
399 return ensure_literal_number(operand, allow_real, allow_imaginary);
400}
401
402static int
403ensure_literal_complex(expr_ty exp)
404{
405 assert(exp->kind == BinOp_kind);
406 expr_ty left = exp->v.BinOp.left;
407 expr_ty right = exp->v.BinOp.right;
408 // Ensure op is addition or subtraction
409 if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
410 return 0;
411 }
412 // Check LHS is a real number (potentially signed)
413 switch (left->kind)
414 {
415 case Constant_kind:
416 if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
417 return 0;
418 }
419 break;
420 case UnaryOp_kind:
421 if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
422 return 0;
423 }
424 break;
425 default:
426 return 0;
427 }
428 // Check RHS is an imaginary number (no separate sign allowed)
429 switch (right->kind)
430 {
431 case Constant_kind:
432 if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
433 return 0;
434 }
435 break;
436 default:
437 return 0;
438 }
Brandt Bucher145bf262021-02-26 14:51:55 -0800439 return 1;
440}
441
442static int
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000443validate_pattern_match_value(struct validator *state, expr_ty exp)
444{
445 if (!validate_expr(state, exp, Load)) {
446 return 0;
447 }
448
449 switch (exp->kind)
450 {
451 case Constant_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300452 /* Ellipsis and immutable sequences are not allowed.
453 For True, False and None, MatchSingleton() should
454 be used */
455 if (!validate_expr(state, exp, Load)) {
456 return 0;
457 }
458 PyObject *literal = exp->v.Constant.value;
459 if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) ||
460 PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) ||
461 PyUnicode_CheckExact(literal)) {
462 return 1;
463 }
464 PyErr_SetString(PyExc_ValueError,
465 "unexpected constant inside of a literal pattern");
466 return 0;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000467 case Attribute_kind:
468 // Constants and attribute lookups are always permitted
469 return 1;
470 case UnaryOp_kind:
471 // Negated numbers are permitted (whether real or imaginary)
472 // Compiler will complain if AST folding doesn't create a constant
473 if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
474 return 1;
475 }
476 break;
477 case BinOp_kind:
478 // Complex literals are permitted
479 // Compiler will complain if AST folding doesn't create a constant
480 if (ensure_literal_complex(exp)) {
481 return 1;
482 }
483 break;
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300484 case JoinedStr_kind:
485 // Handled in the later stages
486 return 1;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000487 default:
488 break;
489 }
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300490 PyErr_SetString(PyExc_ValueError,
491 "patterns may only match literals and attribute lookups");
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000492 return 0;
493}
494
495static int
496validate_pattern(struct validator *state, pattern_ty p)
497{
498 int ret = -1;
499 if (++state->recursion_depth > state->recursion_limit) {
500 PyErr_SetString(PyExc_RecursionError,
501 "maximum recursion depth exceeded during compilation");
502 return 0;
503 }
504 // Coming soon: https://bugs.python.org/issue43897 (thanks Batuhan)!
505 // TODO: Ensure no subnodes use "_" as an ordinary identifier
506 switch (p->kind) {
507 case MatchValue_kind:
508 ret = validate_pattern_match_value(state, p->v.MatchValue.value);
509 break;
510 case MatchSingleton_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300511 ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value);
512 if (!ret) {
513 PyErr_SetString(PyExc_ValueError,
514 "MatchSingleton can only contain True, False and None");
515 }
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000516 break;
517 case MatchSequence_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300518 ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000519 break;
520 case MatchMapping_kind:
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000521 if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
522 PyErr_SetString(PyExc_ValueError,
523 "MatchMapping doesn't have the same number of keys as patterns");
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300524 ret = 0;
525 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000526 }
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300527
528 if (p->v.MatchMapping.rest && !validate_name(p->v.MatchMapping.rest)) {
529 ret = 0;
530 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000531 }
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300532
533 asdl_expr_seq *keys = p->v.MatchMapping.keys;
534 for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) {
535 expr_ty key = asdl_seq_GET(keys, i);
536 if (key->kind == Constant_kind) {
537 PyObject *literal = key->v.Constant.value;
538 if (literal == Py_None || PyBool_Check(literal)) {
539 /* validate_pattern_match_value will ensure the key
540 doesn't contain True, False and None but it is
541 syntactically valid, so we will pass those on in
542 a special case. */
543 continue;
544 }
545 }
546 if (!validate_pattern_match_value(state, key)) {
547 ret = 0;
548 break;
549 }
550 }
551
552 ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000553 break;
554 case MatchClass_kind:
555 if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
556 PyErr_SetString(PyExc_ValueError,
557 "MatchClass doesn't have the same number of keyword attributes as patterns");
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300558 ret = 0;
559 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000560 }
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000561 if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300562 ret = 0;
563 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000564 }
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300565
566 expr_ty cls = p->v.MatchClass.cls;
567 while (1) {
568 if (cls->kind == Name_kind) {
569 break;
570 }
571 else if (cls->kind == Attribute_kind) {
572 cls = cls->v.Attribute.value;
573 continue;
574 }
575 else {
576 PyErr_SetString(PyExc_ValueError,
577 "MatchClass cls field can only contain Name or Attribute nodes.");
578 state->recursion_depth--;
579 return 0;
580 }
581 }
582
583 for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
584 PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
585 if (!validate_name(identifier)) {
586 state->recursion_depth--;
587 return 0;
588 }
589 }
590
591 if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
592 ret = 0;
593 break;
594 }
595
596 ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000597 break;
598 case MatchStar_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300599 ret = p->v.MatchStar.name == NULL || validate_name(p->v.MatchStar.name);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000600 break;
601 case MatchAs_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300602 if (p->v.MatchAs.name && !validate_name(p->v.MatchAs.name)) {
603 ret = 0;
604 break;
605 }
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000606 if (p->v.MatchAs.pattern == NULL) {
607 ret = 1;
608 }
609 else if (p->v.MatchAs.name == NULL) {
610 PyErr_SetString(PyExc_ValueError,
611 "MatchAs must specify a target name if a pattern is given");
612 return 0;
613 }
614 else {
615 ret = validate_pattern(state, p->v.MatchAs.pattern);
616 }
617 break;
618 case MatchOr_kind:
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300619 if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) {
620 PyErr_SetString(PyExc_ValueError,
621 "MatchOr requires at least 2 patterns");
622 ret = 0;
623 break;
624 }
625 ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000626 break;
627 // No default case, so the compiler will emit a warning if new pattern
628 // kinds are added without being handled here
629 }
630 if (ret < 0) {
631 PyErr_SetString(PyExc_SystemError, "unexpected pattern");
632 ret = 0;
633 }
634 state->recursion_depth--;
635 return ret;
636}
637
638static int
Pablo Galindoa5634c42020-09-16 19:42:00 +0100639_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500640{
641 if (asdl_seq_LEN(seq))
642 return 1;
643 PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
644 return 0;
645}
Pablo Galindoa5634c42020-09-16 19:42:00 +0100646#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500647
648static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300649validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500650{
651 return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300652 validate_exprs(state, targets, ctx, 0);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500653}
654
655static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300656validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500657{
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300658 return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500659}
660
661static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300662validate_stmt(struct validator *state, stmt_ty stmt)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500663{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000664 int ret = -1;
Victor Stinner4d73ae72018-11-22 14:45:16 +0100665 Py_ssize_t i;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300666 if (++state->recursion_depth > state->recursion_limit) {
667 PyErr_SetString(PyExc_RecursionError,
668 "maximum recursion depth exceeded during compilation");
669 return 0;
670 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500671 switch (stmt->kind) {
672 case FunctionDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300673 ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
674 validate_arguments(state, stmt->v.FunctionDef.args) &&
675 validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500676 (!stmt->v.FunctionDef.returns ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300677 validate_expr(state, stmt->v.FunctionDef.returns, Load));
678 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500679 case ClassDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300680 ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
681 validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
682 validate_keywords(state, stmt->v.ClassDef.keywords) &&
683 validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
684 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500685 case Return_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300686 ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
687 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500688 case Delete_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300689 ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
690 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500691 case Assign_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300692 ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
693 validate_expr(state, stmt->v.Assign.value, Load);
694 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500695 case AugAssign_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300696 ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
697 validate_expr(state, stmt->v.AugAssign.value, Load);
698 break;
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700699 case AnnAssign_kind:
700 if (stmt->v.AnnAssign.target->kind != Name_kind &&
701 stmt->v.AnnAssign.simple) {
702 PyErr_SetString(PyExc_TypeError,
703 "AnnAssign with simple non-Name target");
704 return 0;
705 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300706 ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700707 (!stmt->v.AnnAssign.value ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300708 validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
709 validate_expr(state, stmt->v.AnnAssign.annotation, Load);
710 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500711 case For_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300712 ret = validate_expr(state, stmt->v.For.target, Store) &&
713 validate_expr(state, stmt->v.For.iter, Load) &&
714 validate_body(state, stmt->v.For.body, "For") &&
715 validate_stmts(state, stmt->v.For.orelse);
716 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400717 case AsyncFor_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300718 ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
719 validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
720 validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
721 validate_stmts(state, stmt->v.AsyncFor.orelse);
722 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500723 case While_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300724 ret = validate_expr(state, stmt->v.While.test, Load) &&
725 validate_body(state, stmt->v.While.body, "While") &&
726 validate_stmts(state, stmt->v.While.orelse);
727 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500728 case If_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300729 ret = validate_expr(state, stmt->v.If.test, Load) &&
730 validate_body(state, stmt->v.If.body, "If") &&
731 validate_stmts(state, stmt->v.If.orelse);
732 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500733 case With_kind:
734 if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
735 return 0;
736 for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
737 withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300738 if (!validate_expr(state, item->context_expr, Load) ||
739 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500740 return 0;
741 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300742 ret = validate_body(state, stmt->v.With.body, "With");
743 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400744 case AsyncWith_kind:
745 if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
746 return 0;
747 for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
748 withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300749 if (!validate_expr(state, item->context_expr, Load) ||
750 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
Yury Selivanov75445082015-05-11 22:57:16 -0400751 return 0;
752 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300753 ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
754 break;
Brandt Bucher145bf262021-02-26 14:51:55 -0800755 case Match_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300756 if (!validate_expr(state, stmt->v.Match.subject, Load)
Brandt Bucher145bf262021-02-26 14:51:55 -0800757 || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
758 return 0;
759 }
760 for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
761 match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000762 if (!validate_pattern(state, m->pattern)
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300763 || (m->guard && !validate_expr(state, m->guard, Load))
764 || !validate_body(state, m->body, "match_case")) {
Brandt Bucher145bf262021-02-26 14:51:55 -0800765 return 0;
766 }
767 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300768 ret = 1;
769 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500770 case Raise_kind:
771 if (stmt->v.Raise.exc) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300772 ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
773 (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
774 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500775 }
776 if (stmt->v.Raise.cause) {
777 PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
778 return 0;
779 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300780 ret = 1;
781 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500782 case Try_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300783 if (!validate_body(state, stmt->v.Try.body, "Try"))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500784 return 0;
785 if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
786 !asdl_seq_LEN(stmt->v.Try.finalbody)) {
787 PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
788 return 0;
789 }
790 if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
791 asdl_seq_LEN(stmt->v.Try.orelse)) {
792 PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
793 return 0;
794 }
795 for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
796 excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
797 if ((handler->v.ExceptHandler.type &&
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300798 !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
799 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500800 return 0;
801 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300802 ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
803 validate_stmts(state, stmt->v.Try.finalbody)) &&
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500804 (!asdl_seq_LEN(stmt->v.Try.orelse) ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300805 validate_stmts(state, stmt->v.Try.orelse));
806 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500807 case Assert_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300808 ret = validate_expr(state, stmt->v.Assert.test, Load) &&
809 (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
810 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500811 case Import_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300812 ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
813 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500814 case ImportFrom_kind:
Serhiy Storchakafbd15232016-06-27 21:39:12 +0300815 if (stmt->v.ImportFrom.level < 0) {
816 PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500817 return 0;
818 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300819 ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
820 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500821 case Global_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300822 ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
823 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500824 case Nonlocal_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300825 ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
826 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500827 case Expr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300828 ret = validate_expr(state, stmt->v.Expr.value, Load);
829 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400830 case AsyncFunctionDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300831 ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
832 validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
833 validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
Yury Selivanov75445082015-05-11 22:57:16 -0400834 (!stmt->v.AsyncFunctionDef.returns ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300835 validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
836 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500837 case Pass_kind:
838 case Break_kind:
839 case Continue_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300840 ret = 1;
841 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000842 // No default case so compiler emits warning for unhandled cases
843 }
844 if (ret < 0) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500845 PyErr_SetString(PyExc_SystemError, "unexpected statement");
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000846 ret = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500847 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300848 state->recursion_depth--;
849 return ret;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500850}
851
852static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300853validate_stmts(struct validator *state, asdl_stmt_seq *seq)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500854{
Victor Stinner4d73ae72018-11-22 14:45:16 +0100855 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500856 for (i = 0; i < asdl_seq_LEN(seq); i++) {
857 stmt_ty stmt = asdl_seq_GET(seq, i);
858 if (stmt) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300859 if (!validate_stmt(state, stmt))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500860 return 0;
861 }
862 else {
863 PyErr_SetString(PyExc_ValueError,
864 "None disallowed in statement list");
865 return 0;
866 }
867 }
868 return 1;
869}
870
871static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300872validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500873{
Victor Stinner4d73ae72018-11-22 14:45:16 +0100874 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500875 for (i = 0; i < asdl_seq_LEN(exprs); i++) {
876 expr_ty expr = asdl_seq_GET(exprs, i);
877 if (expr) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300878 if (!validate_expr(state, expr, ctx))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500879 return 0;
880 }
881 else if (!null_ok) {
882 PyErr_SetString(PyExc_ValueError,
883 "None disallowed in expression list");
884 return 0;
885 }
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100886
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500887 }
888 return 1;
889}
890
Batuhan Taskaya2f763682021-07-10 03:16:15 +0300891static int
892validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
893{
894 Py_ssize_t i;
895 for (i = 0; i < asdl_seq_LEN(patterns); i++) {
896 pattern_ty pattern = asdl_seq_GET(patterns, i);
897 if (pattern->kind == MatchStar_kind && !star_ok) {
898 PyErr_SetString(PyExc_ValueError,
899 "Can't use MatchStar within this sequence of patterns");
900 return 0;
901 }
902 if (!validate_pattern(state, pattern)) {
903 return 0;
904 }
905 }
906 return 1;
907}
908
909
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300910/* See comments in symtable.c. */
911#define COMPILER_STACK_FRAME_SCALE 3
912
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500913int
Victor Stinnereec8e612021-03-18 14:57:49 +0100914_PyAST_Validate(mod_ty mod)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500915{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000916 int res = -1;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300917 struct validator state;
918 PyThreadState *tstate;
919 int recursion_limit = Py_GetRecursionLimit();
920 int starting_recursion_depth;
921
922 /* Setup recursion depth check counters */
923 tstate = _PyThreadState_GET();
924 if (!tstate) {
925 return 0;
926 }
927 /* Be careful here to prevent overflow. */
928 starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
929 tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth;
930 state.recursion_depth = starting_recursion_depth;
931 state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
932 recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500933
934 switch (mod->kind) {
935 case Module_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300936 res = validate_stmts(&state, mod->v.Module.body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500937 break;
938 case Interactive_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300939 res = validate_stmts(&state, mod->v.Interactive.body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500940 break;
941 case Expression_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300942 res = validate_expr(&state, mod->v.Expression.body, Load);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500943 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000944 case FunctionType_kind:
945 res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
946 validate_expr(&state, mod->v.FunctionType.returns, Load);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500947 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000948 // No default case so compiler emits warning for unhandled cases
949 }
950
951 if (res < 0) {
952 PyErr_SetString(PyExc_SystemError, "impossible module node");
953 return 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500954 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300955
956 /* Check that the recursion depth counting balanced correctly */
957 if (res && state.recursion_depth != starting_recursion_depth) {
958 PyErr_Format(PyExc_SystemError,
959 "AST validator recursion depth mismatch (before=%d, after=%d)",
960 starting_recursion_depth, state.recursion_depth);
961 return 0;
962 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500963 return res;
964}
965
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300966PyObject *
Pablo Galindoa5634c42020-09-16 19:42:00 +0100967_PyAST_GetDocString(asdl_stmt_seq *body)
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300968{
969 if (!asdl_seq_LEN(body)) {
970 return NULL;
971 }
Batuhan Taskaya02a16032020-10-10 20:14:59 +0300972 stmt_ty st = asdl_seq_GET(body, 0);
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300973 if (st->kind != Expr_kind) {
974 return NULL;
975 }
976 expr_ty e = st->v.Expr.value;
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300977 if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
978 return e->v.Constant.value;
979 }
980 return NULL;
981}