blob: 1fc83f6301962d829dfad120c92260459262595f [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 *);
18static int validate_exprs(struct validator *, asdl_expr_seq*, expr_context_ty, int);
Pablo Galindoa5634c42020-09-16 19:42:00 +010019static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030020static int validate_stmt(struct validator *, stmt_ty);
21static int validate_expr(struct validator *, expr_ty, expr_context_ty);
Nick Coghlan1e7b8582021-04-29 15:58:44 +100022static int validate_pattern(struct validator *, pattern_ty);
Benjamin Peterson832bfe22011-08-09 16:15:04 -050023
24static int
Batuhan Taskaya68874a82020-06-06 15:44:16 +030025validate_name(PyObject *name)
26{
27 assert(PyUnicode_Check(name));
28 static const char * const forbidden[] = {
29 "None",
30 "True",
31 "False",
32 NULL
33 };
34 for (int i = 0; forbidden[i] != NULL; i++) {
35 if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
36 PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]);
37 return 0;
38 }
39 }
40 return 1;
41}
42
43static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030044validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050045{
Victor Stinner4d73ae72018-11-22 14:45:16 +010046 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050047 if (!asdl_seq_LEN(gens)) {
48 PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
49 return 0;
50 }
51 for (i = 0; i < asdl_seq_LEN(gens); i++) {
52 comprehension_ty comp = asdl_seq_GET(gens, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030053 if (!validate_expr(state, comp->target, Store) ||
54 !validate_expr(state, comp->iter, Load) ||
55 !validate_exprs(state, comp->ifs, Load, 0))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050056 return 0;
57 }
58 return 1;
59}
60
61static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030062validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050063{
Victor Stinner4d73ae72018-11-22 14:45:16 +010064 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050065 for (i = 0; i < asdl_seq_LEN(keywords); i++)
Serhiy Storchakaface87c2021-04-25 13:38:00 +030066 if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050067 return 0;
68 return 1;
69}
70
71static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030072validate_args(struct validator *state, asdl_arg_seq *args)
Benjamin Peterson832bfe22011-08-09 16:15:04 -050073{
Victor Stinner4d73ae72018-11-22 14:45:16 +010074 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -050075 for (i = 0; i < asdl_seq_LEN(args); i++) {
76 arg_ty arg = asdl_seq_GET(args, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +030077 if (arg->annotation && !validate_expr(state, arg->annotation, Load))
Benjamin Peterson832bfe22011-08-09 16:15:04 -050078 return 0;
79 }
80 return 1;
81}
82
83static const char *
84expr_context_name(expr_context_ty ctx)
85{
86 switch (ctx) {
87 case Load:
88 return "Load";
89 case Store:
90 return "Store";
91 case Del:
92 return "Del";
Nick Coghlan1e7b8582021-04-29 15:58:44 +100093 // No default case so compiler emits warning for unhandled cases
Benjamin Peterson832bfe22011-08-09 16:15:04 -050094 }
Nick Coghlan1e7b8582021-04-29 15:58:44 +100095 Py_UNREACHABLE();
Benjamin Peterson832bfe22011-08-09 16:15:04 -050096}
97
98static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +030099validate_arguments(struct validator *state, arguments_ty args)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500100{
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300101 if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500102 return 0;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100103 }
Benjamin Petersoncda75be2013-03-18 10:48:58 -0700104 if (args->vararg && args->vararg->annotation
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300105 && !validate_expr(state, args->vararg->annotation, Load)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500106 return 0;
107 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300108 if (!validate_args(state, args->kwonlyargs))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500109 return 0;
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100110 if (args->kwarg && args->kwarg->annotation
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300111 && !validate_expr(state, args->kwarg->annotation, Load)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500112 return 0;
113 }
Pablo Galindo2f58a842019-05-31 14:09:49 +0100114 if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500115 PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
116 return 0;
117 }
118 if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
119 PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
120 "kw_defaults on arguments");
121 return 0;
122 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300123 return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500124}
125
126static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300127validate_constant(struct validator *state, PyObject *value)
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100128{
129 if (value == Py_None || value == Py_Ellipsis)
130 return 1;
131
132 if (PyLong_CheckExact(value)
133 || PyFloat_CheckExact(value)
134 || PyComplex_CheckExact(value)
135 || PyBool_Check(value)
136 || PyUnicode_CheckExact(value)
137 || PyBytes_CheckExact(value))
138 return 1;
139
140 if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300141 if (++state->recursion_depth > state->recursion_limit) {
142 PyErr_SetString(PyExc_RecursionError,
143 "maximum recursion depth exceeded during compilation");
144 return 0;
145 }
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100146
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300147 PyObject *it = PyObject_GetIter(value);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100148 if (it == NULL)
149 return 0;
150
151 while (1) {
152 PyObject *item = PyIter_Next(it);
153 if (item == NULL) {
154 if (PyErr_Occurred()) {
155 Py_DECREF(it);
156 return 0;
157 }
158 break;
159 }
160
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300161 if (!validate_constant(state, item)) {
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100162 Py_DECREF(it);
Victor Stinner726f6902016-01-27 00:11:47 +0100163 Py_DECREF(item);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100164 return 0;
165 }
Victor Stinner726f6902016-01-27 00:11:47 +0100166 Py_DECREF(item);
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100167 }
168
169 Py_DECREF(it);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300170 --state->recursion_depth;
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100171 return 1;
172 }
173
Batuhan TaÅŸkaya0ac59f92020-03-19 14:32:28 +0300174 if (!PyErr_Occurred()) {
175 PyErr_Format(PyExc_TypeError,
176 "got an invalid type in Constant: %s",
177 _PyType_Name(Py_TYPE(value)));
178 }
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100179 return 0;
180}
181
182static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300183validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500184{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000185 int ret = -1;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300186 if (++state->recursion_depth > state->recursion_limit) {
187 PyErr_SetString(PyExc_RecursionError,
188 "maximum recursion depth exceeded during compilation");
189 return 0;
190 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500191 int check_ctx = 1;
192 expr_context_ty actual_ctx;
193
194 /* First check expression context. */
195 switch (exp->kind) {
196 case Attribute_kind:
197 actual_ctx = exp->v.Attribute.ctx;
198 break;
199 case Subscript_kind:
200 actual_ctx = exp->v.Subscript.ctx;
201 break;
202 case Starred_kind:
203 actual_ctx = exp->v.Starred.ctx;
204 break;
205 case Name_kind:
Batuhan Taskaya68874a82020-06-06 15:44:16 +0300206 if (!validate_name(exp->v.Name.id)) {
207 return 0;
208 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500209 actual_ctx = exp->v.Name.ctx;
210 break;
211 case List_kind:
212 actual_ctx = exp->v.List.ctx;
213 break;
214 case Tuple_kind:
215 actual_ctx = exp->v.Tuple.ctx;
216 break;
217 default:
218 if (ctx != Load) {
219 PyErr_Format(PyExc_ValueError, "expression which can't be "
220 "assigned to in %s context", expr_context_name(ctx));
221 return 0;
222 }
223 check_ctx = 0;
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100224 /* set actual_ctx to prevent gcc warning */
225 actual_ctx = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500226 }
227 if (check_ctx && actual_ctx != ctx) {
228 PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
229 expr_context_name(ctx), expr_context_name(actual_ctx));
230 return 0;
231 }
232
233 /* Now validate expression. */
234 switch (exp->kind) {
235 case BoolOp_kind:
236 if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
237 PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
238 return 0;
239 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300240 ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
241 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500242 case BinOp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300243 ret = validate_expr(state, exp->v.BinOp.left, Load) &&
244 validate_expr(state, exp->v.BinOp.right, Load);
245 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500246 case UnaryOp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300247 ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
248 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500249 case Lambda_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300250 ret = validate_arguments(state, exp->v.Lambda.args) &&
251 validate_expr(state, exp->v.Lambda.body, Load);
252 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500253 case IfExp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300254 ret = validate_expr(state, exp->v.IfExp.test, Load) &&
255 validate_expr(state, exp->v.IfExp.body, Load) &&
256 validate_expr(state, exp->v.IfExp.orelse, Load);
257 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500258 case Dict_kind:
259 if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
260 PyErr_SetString(PyExc_ValueError,
261 "Dict doesn't have the same number of keys as values");
262 return 0;
263 }
Yury Selivanovb3d53132015-09-01 16:10:49 -0400264 /* null_ok=1 for keys expressions to allow dict unpacking to work in
265 dict literals, i.e. ``{**{a:b}}`` */
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300266 ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
267 validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
268 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500269 case Set_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300270 ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
271 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500272#define COMP(NAME) \
273 case NAME ## _kind: \
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300274 ret = validate_comprehension(state, exp->v.NAME.generators) && \
275 validate_expr(state, exp->v.NAME.elt, Load); \
276 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500277 COMP(ListComp)
278 COMP(SetComp)
279 COMP(GeneratorExp)
280#undef COMP
281 case DictComp_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300282 ret = validate_comprehension(state, exp->v.DictComp.generators) &&
283 validate_expr(state, exp->v.DictComp.key, Load) &&
284 validate_expr(state, exp->v.DictComp.value, Load);
285 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500286 case Yield_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300287 ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
288 break;
Benjamin Peterson527c6222012-01-14 08:58:23 -0500289 case YieldFrom_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300290 ret = validate_expr(state, exp->v.YieldFrom.value, Load);
291 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400292 case Await_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300293 ret = validate_expr(state, exp->v.Await.value, Load);
294 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500295 case Compare_kind:
296 if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
297 PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
298 return 0;
299 }
300 if (asdl_seq_LEN(exp->v.Compare.comparators) !=
301 asdl_seq_LEN(exp->v.Compare.ops)) {
302 PyErr_SetString(PyExc_ValueError, "Compare has a different number "
303 "of comparators and operands");
304 return 0;
305 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300306 ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
307 validate_expr(state, exp->v.Compare.left, Load);
308 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500309 case Call_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300310 ret = validate_expr(state, exp->v.Call.func, Load) &&
311 validate_exprs(state, exp->v.Call.args, Load, 0) &&
312 validate_keywords(state, exp->v.Call.keywords);
313 break;
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100314 case Constant_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300315 if (!validate_constant(state, exp->v.Constant.value)) {
Victor Stinnerf2c1aa12016-01-26 00:40:57 +0100316 return 0;
317 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300318 ret = 1;
319 break;
Eric V. Smith235a6f02015-09-19 14:51:32 -0400320 case JoinedStr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300321 ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
322 break;
Eric V. Smith235a6f02015-09-19 14:51:32 -0400323 case FormattedValue_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300324 if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
Eric V. Smith235a6f02015-09-19 14:51:32 -0400325 return 0;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300326 if (exp->v.FormattedValue.format_spec) {
327 ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
328 break;
329 }
330 ret = 1;
331 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500332 case Attribute_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300333 ret = validate_expr(state, exp->v.Attribute.value, Load);
334 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500335 case Subscript_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300336 ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
337 validate_expr(state, exp->v.Subscript.value, Load);
338 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500339 case Starred_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300340 ret = validate_expr(state, exp->v.Starred.value, ctx);
341 break;
Serhiy Storchaka13d52c22020-03-10 18:52:34 +0200342 case Slice_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300343 ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
344 (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
345 (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
346 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500347 case List_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300348 ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
349 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500350 case Tuple_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300351 ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
352 break;
Pablo Galindo0c9258a2019-03-18 13:51:53 +0000353 case NamedExpr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300354 ret = validate_expr(state, exp->v.NamedExpr.value, Load);
355 break;
Serhiy Storchaka3f228112018-09-27 17:42:37 +0300356 /* This last case doesn't have any checking. */
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500357 case Name_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300358 ret = 1;
359 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000360 // No default case so compiler emits warning for unhandled cases
361 }
362 if (ret < 0) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300363 PyErr_SetString(PyExc_SystemError, "unexpected expression");
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000364 ret = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500365 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300366 state->recursion_depth--;
367 return ret;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500368}
369
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000370
371// Note: the ensure_literal_* functions are only used to validate a restricted
372// set of non-recursive literals that have already been checked with
373// validate_expr, so they don't accept the validator state
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500374static int
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000375ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
Brandt Bucher145bf262021-02-26 14:51:55 -0800376{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000377 assert(exp->kind == Constant_kind);
378 PyObject *value = exp->v.Constant.value;
379 return (allow_real && PyFloat_CheckExact(value)) ||
380 (allow_real && PyLong_CheckExact(value)) ||
381 (allow_imaginary && PyComplex_CheckExact(value));
382}
383
384static int
385ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
386{
387 assert(exp->kind == UnaryOp_kind);
388 // Must be negation ...
389 if (exp->v.UnaryOp.op != USub) {
390 return 0;
391 }
392 // ... of a constant ...
393 expr_ty operand = exp->v.UnaryOp.operand;
394 if (operand->kind != Constant_kind) {
395 return 0;
396 }
397 // ... number
398 return ensure_literal_number(operand, allow_real, allow_imaginary);
399}
400
401static int
402ensure_literal_complex(expr_ty exp)
403{
404 assert(exp->kind == BinOp_kind);
405 expr_ty left = exp->v.BinOp.left;
406 expr_ty right = exp->v.BinOp.right;
407 // Ensure op is addition or subtraction
408 if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
409 return 0;
410 }
411 // Check LHS is a real number (potentially signed)
412 switch (left->kind)
413 {
414 case Constant_kind:
415 if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
416 return 0;
417 }
418 break;
419 case UnaryOp_kind:
420 if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
421 return 0;
422 }
423 break;
424 default:
425 return 0;
426 }
427 // Check RHS is an imaginary number (no separate sign allowed)
428 switch (right->kind)
429 {
430 case Constant_kind:
431 if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
432 return 0;
433 }
434 break;
435 default:
436 return 0;
437 }
Brandt Bucher145bf262021-02-26 14:51:55 -0800438 return 1;
439}
440
441static int
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000442validate_pattern_match_value(struct validator *state, expr_ty exp)
443{
444 if (!validate_expr(state, exp, Load)) {
445 return 0;
446 }
447
448 switch (exp->kind)
449 {
450 case Constant_kind:
451 case Attribute_kind:
452 // Constants and attribute lookups are always permitted
453 return 1;
454 case UnaryOp_kind:
455 // Negated numbers are permitted (whether real or imaginary)
456 // Compiler will complain if AST folding doesn't create a constant
457 if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
458 return 1;
459 }
460 break;
461 case BinOp_kind:
462 // Complex literals are permitted
463 // Compiler will complain if AST folding doesn't create a constant
464 if (ensure_literal_complex(exp)) {
465 return 1;
466 }
467 break;
468 default:
469 break;
470 }
471 PyErr_SetString(PyExc_SyntaxError,
472 "patterns may only match literals and attribute lookups");
473 return 0;
474}
475
476static int
477validate_pattern(struct validator *state, pattern_ty p)
478{
479 int ret = -1;
480 if (++state->recursion_depth > state->recursion_limit) {
481 PyErr_SetString(PyExc_RecursionError,
482 "maximum recursion depth exceeded during compilation");
483 return 0;
484 }
485 // Coming soon: https://bugs.python.org/issue43897 (thanks Batuhan)!
486 // TODO: Ensure no subnodes use "_" as an ordinary identifier
487 switch (p->kind) {
488 case MatchValue_kind:
489 ret = validate_pattern_match_value(state, p->v.MatchValue.value);
490 break;
491 case MatchSingleton_kind:
492 // TODO: Check constant is specifically None, True, or False
493 ret = validate_constant(state, p->v.MatchSingleton.value);
494 break;
495 case MatchSequence_kind:
496 // TODO: Validate all subpatterns
497 // return validate_patterns(state, p->v.MatchSequence.patterns);
498 ret = 1;
499 break;
500 case MatchMapping_kind:
501 // TODO: check "rest" target name is valid
502 if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
503 PyErr_SetString(PyExc_ValueError,
504 "MatchMapping doesn't have the same number of keys as patterns");
505 return 0;
506 }
507 // null_ok=0 for key expressions, as rest-of-mapping is captured in "rest"
508 // TODO: replace with more restrictive expression validator, as per MatchValue above
509 if (!validate_exprs(state, p->v.MatchMapping.keys, Load, /*null_ok=*/ 0)) {
510 return 0;
511 }
512 // TODO: Validate all subpatterns
513 // ret = validate_patterns(state, p->v.MatchMapping.patterns);
514 ret = 1;
515 break;
516 case MatchClass_kind:
517 if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
518 PyErr_SetString(PyExc_ValueError,
519 "MatchClass doesn't have the same number of keyword attributes as patterns");
520 return 0;
521 }
522 // TODO: Restrict cls lookup to being a name or attribute
523 if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
524 return 0;
525 }
526 // TODO: Validate all subpatterns
527 // return validate_patterns(state, p->v.MatchClass.patterns) &&
528 // validate_patterns(state, p->v.MatchClass.kwd_patterns);
529 ret = 1;
530 break;
531 case MatchStar_kind:
532 // TODO: check target name is valid
533 ret = 1;
534 break;
535 case MatchAs_kind:
536 // TODO: check target name is valid
537 if (p->v.MatchAs.pattern == NULL) {
538 ret = 1;
539 }
540 else if (p->v.MatchAs.name == NULL) {
541 PyErr_SetString(PyExc_ValueError,
542 "MatchAs must specify a target name if a pattern is given");
543 return 0;
544 }
545 else {
546 ret = validate_pattern(state, p->v.MatchAs.pattern);
547 }
548 break;
549 case MatchOr_kind:
550 // TODO: Validate all subpatterns
551 // return validate_patterns(state, p->v.MatchOr.patterns);
552 ret = 1;
553 break;
554 // No default case, so the compiler will emit a warning if new pattern
555 // kinds are added without being handled here
556 }
557 if (ret < 0) {
558 PyErr_SetString(PyExc_SystemError, "unexpected pattern");
559 ret = 0;
560 }
561 state->recursion_depth--;
562 return ret;
563}
564
565static int
Pablo Galindoa5634c42020-09-16 19:42:00 +0100566_validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500567{
568 if (asdl_seq_LEN(seq))
569 return 1;
570 PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
571 return 0;
572}
Pablo Galindoa5634c42020-09-16 19:42:00 +0100573#define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500574
575static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300576validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500577{
578 return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300579 validate_exprs(state, targets, ctx, 0);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500580}
581
582static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300583validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500584{
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300585 return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500586}
587
588static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300589validate_stmt(struct validator *state, stmt_ty stmt)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500590{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000591 int ret = -1;
Victor Stinner4d73ae72018-11-22 14:45:16 +0100592 Py_ssize_t i;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300593 if (++state->recursion_depth > state->recursion_limit) {
594 PyErr_SetString(PyExc_RecursionError,
595 "maximum recursion depth exceeded during compilation");
596 return 0;
597 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500598 switch (stmt->kind) {
599 case FunctionDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300600 ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
601 validate_arguments(state, stmt->v.FunctionDef.args) &&
602 validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500603 (!stmt->v.FunctionDef.returns ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300604 validate_expr(state, stmt->v.FunctionDef.returns, Load));
605 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500606 case ClassDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300607 ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
608 validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
609 validate_keywords(state, stmt->v.ClassDef.keywords) &&
610 validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
611 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500612 case Return_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300613 ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
614 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500615 case Delete_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300616 ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
617 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500618 case Assign_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300619 ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
620 validate_expr(state, stmt->v.Assign.value, Load);
621 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500622 case AugAssign_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300623 ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
624 validate_expr(state, stmt->v.AugAssign.value, Load);
625 break;
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700626 case AnnAssign_kind:
627 if (stmt->v.AnnAssign.target->kind != Name_kind &&
628 stmt->v.AnnAssign.simple) {
629 PyErr_SetString(PyExc_TypeError,
630 "AnnAssign with simple non-Name target");
631 return 0;
632 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300633 ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
Yury Selivanovf8cb8a12016-09-08 20:50:03 -0700634 (!stmt->v.AnnAssign.value ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300635 validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
636 validate_expr(state, stmt->v.AnnAssign.annotation, Load);
637 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500638 case For_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300639 ret = validate_expr(state, stmt->v.For.target, Store) &&
640 validate_expr(state, stmt->v.For.iter, Load) &&
641 validate_body(state, stmt->v.For.body, "For") &&
642 validate_stmts(state, stmt->v.For.orelse);
643 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400644 case AsyncFor_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300645 ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
646 validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
647 validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
648 validate_stmts(state, stmt->v.AsyncFor.orelse);
649 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500650 case While_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300651 ret = validate_expr(state, stmt->v.While.test, Load) &&
652 validate_body(state, stmt->v.While.body, "While") &&
653 validate_stmts(state, stmt->v.While.orelse);
654 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500655 case If_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300656 ret = validate_expr(state, stmt->v.If.test, Load) &&
657 validate_body(state, stmt->v.If.body, "If") &&
658 validate_stmts(state, stmt->v.If.orelse);
659 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500660 case With_kind:
661 if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
662 return 0;
663 for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
664 withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300665 if (!validate_expr(state, item->context_expr, Load) ||
666 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500667 return 0;
668 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300669 ret = validate_body(state, stmt->v.With.body, "With");
670 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400671 case AsyncWith_kind:
672 if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
673 return 0;
674 for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
675 withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300676 if (!validate_expr(state, item->context_expr, Load) ||
677 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
Yury Selivanov75445082015-05-11 22:57:16 -0400678 return 0;
679 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300680 ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
681 break;
Brandt Bucher145bf262021-02-26 14:51:55 -0800682 case Match_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300683 if (!validate_expr(state, stmt->v.Match.subject, Load)
Brandt Bucher145bf262021-02-26 14:51:55 -0800684 || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
685 return 0;
686 }
687 for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
688 match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000689 if (!validate_pattern(state, m->pattern)
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300690 || (m->guard && !validate_expr(state, m->guard, Load))
691 || !validate_body(state, m->body, "match_case")) {
Brandt Bucher145bf262021-02-26 14:51:55 -0800692 return 0;
693 }
694 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300695 ret = 1;
696 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500697 case Raise_kind:
698 if (stmt->v.Raise.exc) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300699 ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
700 (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
701 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500702 }
703 if (stmt->v.Raise.cause) {
704 PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
705 return 0;
706 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300707 ret = 1;
708 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500709 case Try_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300710 if (!validate_body(state, stmt->v.Try.body, "Try"))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500711 return 0;
712 if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
713 !asdl_seq_LEN(stmt->v.Try.finalbody)) {
714 PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
715 return 0;
716 }
717 if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
718 asdl_seq_LEN(stmt->v.Try.orelse)) {
719 PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
720 return 0;
721 }
722 for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
723 excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
724 if ((handler->v.ExceptHandler.type &&
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300725 !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
726 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500727 return 0;
728 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300729 ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
730 validate_stmts(state, stmt->v.Try.finalbody)) &&
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500731 (!asdl_seq_LEN(stmt->v.Try.orelse) ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300732 validate_stmts(state, stmt->v.Try.orelse));
733 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500734 case Assert_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300735 ret = validate_expr(state, stmt->v.Assert.test, Load) &&
736 (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
737 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500738 case Import_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300739 ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
740 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500741 case ImportFrom_kind:
Serhiy Storchakafbd15232016-06-27 21:39:12 +0300742 if (stmt->v.ImportFrom.level < 0) {
743 PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500744 return 0;
745 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300746 ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
747 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500748 case Global_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300749 ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
750 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500751 case Nonlocal_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300752 ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
753 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500754 case Expr_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300755 ret = validate_expr(state, stmt->v.Expr.value, Load);
756 break;
Yury Selivanov75445082015-05-11 22:57:16 -0400757 case AsyncFunctionDef_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300758 ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
759 validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
760 validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
Yury Selivanov75445082015-05-11 22:57:16 -0400761 (!stmt->v.AsyncFunctionDef.returns ||
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300762 validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
763 break;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500764 case Pass_kind:
765 case Break_kind:
766 case Continue_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300767 ret = 1;
768 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000769 // No default case so compiler emits warning for unhandled cases
770 }
771 if (ret < 0) {
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500772 PyErr_SetString(PyExc_SystemError, "unexpected statement");
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000773 ret = 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500774 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300775 state->recursion_depth--;
776 return ret;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500777}
778
779static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300780validate_stmts(struct validator *state, asdl_stmt_seq *seq)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500781{
Victor Stinner4d73ae72018-11-22 14:45:16 +0100782 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500783 for (i = 0; i < asdl_seq_LEN(seq); i++) {
784 stmt_ty stmt = asdl_seq_GET(seq, i);
785 if (stmt) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300786 if (!validate_stmt(state, stmt))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500787 return 0;
788 }
789 else {
790 PyErr_SetString(PyExc_ValueError,
791 "None disallowed in statement list");
792 return 0;
793 }
794 }
795 return 1;
796}
797
798static int
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300799validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500800{
Victor Stinner4d73ae72018-11-22 14:45:16 +0100801 Py_ssize_t i;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500802 for (i = 0; i < asdl_seq_LEN(exprs); i++) {
803 expr_ty expr = asdl_seq_GET(exprs, i);
804 if (expr) {
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300805 if (!validate_expr(state, expr, ctx))
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500806 return 0;
807 }
808 else if (!null_ok) {
809 PyErr_SetString(PyExc_ValueError,
810 "None disallowed in expression list");
811 return 0;
812 }
Victor Stinner0c39b1b2015-03-18 15:02:06 +0100813
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500814 }
815 return 1;
816}
817
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300818/* See comments in symtable.c. */
819#define COMPILER_STACK_FRAME_SCALE 3
820
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500821int
Victor Stinnereec8e612021-03-18 14:57:49 +0100822_PyAST_Validate(mod_ty mod)
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500823{
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000824 int res = -1;
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300825 struct validator state;
826 PyThreadState *tstate;
827 int recursion_limit = Py_GetRecursionLimit();
828 int starting_recursion_depth;
829
830 /* Setup recursion depth check counters */
831 tstate = _PyThreadState_GET();
832 if (!tstate) {
833 return 0;
834 }
835 /* Be careful here to prevent overflow. */
836 starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
837 tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth;
838 state.recursion_depth = starting_recursion_depth;
839 state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
840 recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500841
842 switch (mod->kind) {
843 case Module_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300844 res = validate_stmts(&state, mod->v.Module.body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500845 break;
846 case Interactive_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300847 res = validate_stmts(&state, mod->v.Interactive.body);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500848 break;
849 case Expression_kind:
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300850 res = validate_expr(&state, mod->v.Expression.body, Load);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500851 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000852 case FunctionType_kind:
853 res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
854 validate_expr(&state, mod->v.FunctionType.returns, Load);
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500855 break;
Nick Coghlan1e7b8582021-04-29 15:58:44 +1000856 // No default case so compiler emits warning for unhandled cases
857 }
858
859 if (res < 0) {
860 PyErr_SetString(PyExc_SystemError, "impossible module node");
861 return 0;
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500862 }
Serhiy Storchakaface87c2021-04-25 13:38:00 +0300863
864 /* Check that the recursion depth counting balanced correctly */
865 if (res && state.recursion_depth != starting_recursion_depth) {
866 PyErr_Format(PyExc_SystemError,
867 "AST validator recursion depth mismatch (before=%d, after=%d)",
868 starting_recursion_depth, state.recursion_depth);
869 return 0;
870 }
Benjamin Peterson832bfe22011-08-09 16:15:04 -0500871 return res;
872}
873
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300874PyObject *
Pablo Galindoa5634c42020-09-16 19:42:00 +0100875_PyAST_GetDocString(asdl_stmt_seq *body)
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300876{
877 if (!asdl_seq_LEN(body)) {
878 return NULL;
879 }
Batuhan Taskaya02a16032020-10-10 20:14:59 +0300880 stmt_ty st = asdl_seq_GET(body, 0);
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300881 if (st->kind != Expr_kind) {
882 return NULL;
883 }
884 expr_ty e = st->v.Expr.value;
Serhiy Storchaka143ce5c2018-05-30 10:56:16 +0300885 if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
886 return e->v.Constant.value;
887 }
888 return NULL;
889}