Branch data Line data Source code
1 : : /*
2 : : * This file exposes PyAST_Validate interface to check the integrity
3 : : * of the given abstract syntax tree (potentially constructed manually).
4 : : */
5 : : #include "Python.h"
6 : : #include "pycore_ast.h" // asdl_stmt_seq
7 : : #include "pycore_pystate.h" // _PyThreadState_GET()
8 : :
9 : : #include <assert.h>
10 : : #include <stdbool.h>
11 : :
12 : : struct validator {
13 : : int recursion_depth; /* current recursion depth */
14 : : int recursion_limit; /* recursion limit */
15 : : };
16 : :
17 : : static int validate_stmts(struct validator *, asdl_stmt_seq *);
18 : : static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
19 : : static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
20 : : static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
21 : : static int validate_stmt(struct validator *, stmt_ty);
22 : : static int validate_expr(struct validator *, expr_ty, expr_context_ty);
23 : : static int validate_pattern(struct validator *, pattern_ty, int);
24 : :
25 : : #define VALIDATE_POSITIONS(node) \
26 : : if (node->lineno > node->end_lineno) { \
27 : : PyErr_Format(PyExc_ValueError, \
28 : : "AST node line range (%d, %d) is not valid", \
29 : : node->lineno, node->end_lineno); \
30 : : return 0; \
31 : : } \
32 : : if ((node->lineno < 0 && node->end_lineno != node->lineno) || \
33 : : (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \
34 : : PyErr_Format(PyExc_ValueError, \
35 : : "AST node column range (%d, %d) for line range (%d, %d) is not valid", \
36 : : node->col_offset, node->end_col_offset, node->lineno, node->end_lineno); \
37 : : return 0; \
38 : : } \
39 : : if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \
40 : : PyErr_Format(PyExc_ValueError, \
41 : : "line %d, column %d-%d is not a valid range", \
42 : : node->lineno, node->col_offset, node->end_col_offset); \
43 : : return 0; \
44 : : }
45 : :
46 : : static int
47 : 119382 : validate_name(PyObject *name)
48 : : {
49 : : assert(PyUnicode_Check(name));
50 : : static const char * const forbidden[] = {
51 : : "None",
52 : : "True",
53 : : "False",
54 : : NULL
55 : : };
56 [ + + ]: 477515 : for (int i = 0; forbidden[i] != NULL; i++) {
57 [ + + ]: 358140 : if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
58 : 7 : PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]);
59 : 7 : return 0;
60 : : }
61 : : }
62 : 119375 : return 1;
63 : : }
64 : :
65 : : static int
66 : 612 : validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
67 : : {
68 : : Py_ssize_t i;
69 [ + - + + ]: 612 : if (!asdl_seq_LEN(gens)) {
70 : 4 : PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
71 : 4 : return 0;
72 : : }
73 [ + - + + ]: 1227 : for (i = 0; i < asdl_seq_LEN(gens); i++) {
74 : 635 : comprehension_ty comp = asdl_seq_GET(gens, i);
75 [ + + + + ]: 1266 : if (!validate_expr(state, comp->target, Store) ||
76 [ + + ]: 1258 : !validate_expr(state, comp->iter, Load) ||
77 : 627 : !validate_exprs(state, comp->ifs, Load, 0))
78 : 16 : return 0;
79 : : }
80 : 592 : return 1;
81 : : }
82 : :
83 : : static int
84 : 30949 : validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
85 : : {
86 : : Py_ssize_t i;
87 [ + - + + ]: 34250 : for (i = 0; i < asdl_seq_LEN(keywords); i++)
88 [ + + ]: 3303 : if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
89 : 2 : return 0;
90 : 30947 : return 1;
91 : : }
92 : :
93 : : static int
94 : 22794 : validate_args(struct validator *state, asdl_arg_seq *args)
95 : : {
96 : : Py_ssize_t i;
97 [ + - + + ]: 37517 : for (i = 0; i < asdl_seq_LEN(args); i++) {
98 : 14729 : arg_ty arg = asdl_seq_GET(args, i);
99 [ - + - + : 14729 : VALIDATE_POSITIONS(arg);
- - - + -
- + - -
+ ]
100 [ + + + + ]: 14729 : if (arg->annotation && !validate_expr(state, arg->annotation, Load))
101 : 6 : return 0;
102 : : }
103 : 22788 : return 1;
104 : : }
105 : :
106 : : static const char *
107 : 173 : expr_context_name(expr_context_ty ctx)
108 : : {
109 [ + + + - ]: 173 : switch (ctx) {
110 : 86 : case Load:
111 : 86 : return "Load";
112 : 86 : case Store:
113 : 86 : return "Store";
114 : 1 : case Del:
115 : 1 : return "Del";
116 : : // No default case so compiler emits warning for unhandled cases
117 : : }
118 : 0 : Py_UNREACHABLE();
119 : : }
120 : :
121 : : static int
122 : 7600 : validate_arguments(struct validator *state, arguments_ty args)
123 : : {
124 [ + + + + ]: 7600 : if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
125 : 4 : return 0;
126 : : }
127 [ + + + + ]: 7596 : if (args->vararg && args->vararg->annotation
128 [ - + ]: 10 : && !validate_expr(state, args->vararg->annotation, Load)) {
129 : 0 : return 0;
130 : : }
131 [ + + ]: 7596 : if (!validate_args(state, args->kwonlyargs))
132 : 2 : return 0;
133 [ + + + + ]: 7594 : if (args->kwarg && args->kwarg->annotation
134 [ - + ]: 4 : && !validate_expr(state, args->kwarg->annotation, Load)) {
135 : 0 : return 0;
136 : : }
137 [ + - + - : 7594 : if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
+ - + + ]
138 : 2 : PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
139 : 2 : return 0;
140 : : }
141 [ + - + - : 7592 : if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
+ + ]
142 : 2 : PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
143 : : "kw_defaults on arguments");
144 : 2 : return 0;
145 : : }
146 [ + + + + ]: 7590 : return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
147 : : }
148 : :
149 : : static int
150 : 46707 : validate_constant(struct validator *state, PyObject *value)
151 : : {
152 [ + + + + ]: 46707 : if (value == Py_None || value == Py_Ellipsis)
153 : 4888 : return 1;
154 : :
155 [ + + ]: 41819 : if (PyLong_CheckExact(value)
156 [ + + ]: 29092 : || PyFloat_CheckExact(value)
157 [ + + ]: 28649 : || PyComplex_CheckExact(value)
158 [ + + ]: 28637 : || PyBool_Check(value)
159 [ + + ]: 26371 : || PyUnicode_CheckExact(value)
160 [ + + ]: 843 : || PyBytes_CheckExact(value))
161 : 41796 : return 1;
162 : :
163 [ + + + + ]: 23 : if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
164 [ - + ]: 16 : if (++state->recursion_depth > state->recursion_limit) {
165 : 0 : PyErr_SetString(PyExc_RecursionError,
166 : : "maximum recursion depth exceeded during compilation");
167 : 0 : return 0;
168 : : }
169 : :
170 : 16 : PyObject *it = PyObject_GetIter(value);
171 [ + - ]: 16 : if (it == NULL)
172 : 0 : return 0;
173 : :
174 : 40 : while (1) {
175 : 56 : PyObject *item = PyIter_Next(it);
176 [ + + ]: 56 : if (item == NULL) {
177 [ - + ]: 14 : if (PyErr_Occurred()) {
178 : 0 : Py_DECREF(it);
179 : 0 : return 0;
180 : : }
181 : 14 : break;
182 : : }
183 : :
184 [ + + ]: 42 : if (!validate_constant(state, item)) {
185 : 2 : Py_DECREF(it);
186 : 2 : Py_DECREF(item);
187 : 2 : return 0;
188 : : }
189 : 40 : Py_DECREF(item);
190 : : }
191 : :
192 : 14 : Py_DECREF(it);
193 : 14 : --state->recursion_depth;
194 : 14 : return 1;
195 : : }
196 : :
197 [ + - ]: 7 : if (!PyErr_Occurred()) {
198 : 7 : PyErr_Format(PyExc_TypeError,
199 : : "got an invalid type in Constant: %s",
200 : : _PyType_Name(Py_TYPE(value)));
201 : : }
202 : 7 : return 0;
203 : : }
204 : :
205 : : static int
206 : 267487 : validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
207 : : {
208 [ - + - + : 267487 : VALIDATE_POSITIONS(exp);
- - - + -
- + + -
+ ]
209 : 267487 : int ret = -1;
210 [ - + ]: 267487 : if (++state->recursion_depth > state->recursion_limit) {
211 : 0 : PyErr_SetString(PyExc_RecursionError,
212 : : "maximum recursion depth exceeded during compilation");
213 : 0 : return 0;
214 : : }
215 : 267487 : int check_ctx = 1;
216 : : expr_context_ty actual_ctx;
217 : :
218 : : /* First check expression context. */
219 [ + + + + : 267487 : switch (exp->kind) {
+ + + ]
220 : 35088 : case Attribute_kind:
221 : 35088 : actual_ctx = exp->v.Attribute.ctx;
222 : 35088 : break;
223 : 4948 : case Subscript_kind:
224 : 4948 : actual_ctx = exp->v.Subscript.ctx;
225 : 4948 : break;
226 : 316 : case Starred_kind:
227 : 316 : actual_ctx = exp->v.Starred.ctx;
228 : 316 : break;
229 : 119374 : case Name_kind:
230 [ + + ]: 119374 : if (!validate_name(exp->v.Name.id)) {
231 : 3 : return 0;
232 : : }
233 : 119371 : actual_ctx = exp->v.Name.ctx;
234 : 119371 : break;
235 : 1489 : case List_kind:
236 : 1489 : actual_ctx = exp->v.List.ctx;
237 : 1489 : break;
238 : 5243 : case Tuple_kind:
239 : 5243 : actual_ctx = exp->v.Tuple.ctx;
240 : 5243 : break;
241 : 101029 : default:
242 [ + + ]: 101029 : if (ctx != Load) {
243 : 1 : PyErr_Format(PyExc_ValueError, "expression which can't be "
244 : : "assigned to in %s context", expr_context_name(ctx));
245 : 1 : return 0;
246 : : }
247 : 101028 : check_ctx = 0;
248 : : /* set actual_ctx to prevent gcc warning */
249 : 101028 : actual_ctx = 0;
250 : : }
251 [ + + + + ]: 267483 : if (check_ctx && actual_ctx != ctx) {
252 : 86 : PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
253 : : expr_context_name(ctx), expr_context_name(actual_ctx));
254 : 86 : return 0;
255 : : }
256 : :
257 : : /* Now validate expression. */
258 [ + + + + : 267397 : switch (exp->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + - ]
259 : 2070 : case BoolOp_kind:
260 [ + - + + ]: 2070 : if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
261 : 2 : PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
262 : 2 : return 0;
263 : : }
264 : 2068 : ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
265 : 2068 : break;
266 : 6682 : case BinOp_kind:
267 [ + - + - ]: 13364 : ret = validate_expr(state, exp->v.BinOp.left, Load) &&
268 : 6682 : validate_expr(state, exp->v.BinOp.right, Load);
269 : 6682 : break;
270 : 2999 : case UnaryOp_kind:
271 : 2999 : ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
272 : 2999 : break;
273 : 168 : case Lambda_kind:
274 [ + + + + ]: 329 : ret = validate_arguments(state, exp->v.Lambda.args) &&
275 : 161 : validate_expr(state, exp->v.Lambda.body, Load);
276 : 168 : break;
277 : 238 : case IfExp_kind:
278 [ + + ]: 475 : ret = validate_expr(state, exp->v.IfExp.test, Load) &&
279 [ + + + + ]: 475 : validate_expr(state, exp->v.IfExp.body, Load) &&
280 : 236 : validate_expr(state, exp->v.IfExp.orelse, Load);
281 : 238 : break;
282 : 625 : case Dict_kind:
283 [ + - + - : 625 : if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
+ + ]
284 : 1 : PyErr_SetString(PyExc_ValueError,
285 : : "Dict doesn't have the same number of keys as values");
286 : 1 : return 0;
287 : : }
288 : : /* null_ok=1 for keys expressions to allow dict unpacking to work in
289 : : dict literals, i.e. ``{**{a:b}}`` */
290 [ + - + + ]: 1248 : ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
291 : 624 : validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
292 : 624 : break;
293 : 114 : case Set_kind:
294 : 114 : ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
295 : 114 : break;
296 : : #define COMP(NAME) \
297 : : case NAME ## _kind: \
298 : : ret = validate_comprehension(state, exp->v.NAME.generators) && \
299 : : validate_expr(state, exp->v.NAME.elt, Load); \
300 : : break;
301 [ + + + + ]: 320 : COMP(ListComp)
302 [ + + + + ]: 23 : COMP(SetComp)
303 [ + + + + ]: 232 : COMP(GeneratorExp)
304 : : #undef COMP
305 : 37 : case DictComp_kind:
306 [ + + ]: 69 : ret = validate_comprehension(state, exp->v.DictComp.generators) &&
307 [ + + + + ]: 69 : validate_expr(state, exp->v.DictComp.key, Load) &&
308 : 31 : validate_expr(state, exp->v.DictComp.value, Load);
309 : 37 : break;
310 : 210 : case Yield_kind:
311 [ + + + + ]: 210 : ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
312 : 210 : break;
313 : 51 : case YieldFrom_kind:
314 : 51 : ret = validate_expr(state, exp->v.YieldFrom.value, Load);
315 : 51 : break;
316 : 14 : case Await_kind:
317 : 14 : ret = validate_expr(state, exp->v.Await.value, Load);
318 : 14 : break;
319 : 8198 : case Compare_kind:
320 [ + - + + ]: 8198 : if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
321 : 1 : PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
322 : 1 : return 0;
323 : : }
324 [ + - + + ]: 16394 : if (asdl_seq_LEN(exp->v.Compare.comparators) !=
325 [ + - ]: 8197 : asdl_seq_LEN(exp->v.Compare.ops)) {
326 : 1 : PyErr_SetString(PyExc_ValueError, "Compare has a different number "
327 : : "of comparators and operands");
328 : 1 : return 0;
329 : : }
330 [ + - + - ]: 16392 : ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
331 : 8196 : validate_expr(state, exp->v.Compare.left, Load);
332 : 8196 : break;
333 : 30125 : case Call_kind:
334 [ + + ]: 60249 : ret = validate_expr(state, exp->v.Call.func, Load) &&
335 [ + + + + ]: 60249 : validate_exprs(state, exp->v.Call.args, Load, 0) &&
336 : 30123 : validate_keywords(state, exp->v.Call.keywords);
337 : 30125 : break;
338 : 46665 : case Constant_kind:
339 [ + + ]: 46665 : if (!validate_constant(state, exp->v.Constant.value)) {
340 : 7 : return 0;
341 : : }
342 : 46658 : ret = 1;
343 : 46658 : break;
344 : 389 : case JoinedStr_kind:
345 : 389 : ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
346 : 389 : break;
347 : 552 : case FormattedValue_kind:
348 [ - + ]: 552 : if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
349 : 0 : return 0;
350 [ + + ]: 552 : if (exp->v.FormattedValue.format_spec) {
351 : 19 : ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
352 : 19 : break;
353 : : }
354 : 533 : ret = 1;
355 : 533 : break;
356 : 35087 : case Attribute_kind:
357 : 35087 : ret = validate_expr(state, exp->v.Attribute.value, Load);
358 : 35087 : break;
359 : 4948 : case Subscript_kind:
360 [ + + + + ]: 9891 : ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
361 : 4943 : validate_expr(state, exp->v.Subscript.value, Load);
362 : 4948 : break;
363 : 316 : case Starred_kind:
364 : 316 : ret = validate_expr(state, exp->v.Starred.value, ctx);
365 : 316 : break;
366 : 1294 : case Slice_kind:
367 [ + + ]: 774 : ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
368 [ + + + + : 3360 : (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
+ + ]
369 [ + + + + ]: 1292 : (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
370 : 1294 : break;
371 : 1489 : case List_kind:
372 : 1489 : ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
373 : 1489 : break;
374 : 5243 : case Tuple_kind:
375 : 5243 : ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
376 : 5243 : break;
377 : 22 : case NamedExpr_kind:
378 : 22 : ret = validate_expr(state, exp->v.NamedExpr.value, Load);
379 : 22 : break;
380 : : /* This last case doesn't have any checking. */
381 : 119286 : case Name_kind:
382 : 119286 : ret = 1;
383 : 119286 : break;
384 : : // No default case so compiler emits warning for unhandled cases
385 : : }
386 [ - + ]: 267385 : if (ret < 0) {
387 : 0 : PyErr_SetString(PyExc_SystemError, "unexpected expression");
388 : 0 : ret = 0;
389 : : }
390 : 267385 : state->recursion_depth--;
391 : 267385 : return ret;
392 : : }
393 : :
394 : :
395 : : // Note: the ensure_literal_* functions are only used to validate a restricted
396 : : // set of non-recursive literals that have already been checked with
397 : : // validate_expr, so they don't accept the validator state
398 : : static int
399 : 0 : ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
400 : : {
401 : : assert(exp->kind == Constant_kind);
402 : 0 : PyObject *value = exp->v.Constant.value;
403 [ # # # # ]: 0 : return (allow_real && PyFloat_CheckExact(value)) ||
404 [ # # # # : 0 : (allow_real && PyLong_CheckExact(value)) ||
# # ]
405 [ # # ]: 0 : (allow_imaginary && PyComplex_CheckExact(value));
406 : : }
407 : :
408 : : static int
409 : 0 : ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
410 : : {
411 : : assert(exp->kind == UnaryOp_kind);
412 : : // Must be negation ...
413 [ # # ]: 0 : if (exp->v.UnaryOp.op != USub) {
414 : 0 : return 0;
415 : : }
416 : : // ... of a constant ...
417 : 0 : expr_ty operand = exp->v.UnaryOp.operand;
418 [ # # ]: 0 : if (operand->kind != Constant_kind) {
419 : 0 : return 0;
420 : : }
421 : : // ... number
422 : 0 : return ensure_literal_number(operand, allow_real, allow_imaginary);
423 : : }
424 : :
425 : : static int
426 : 0 : ensure_literal_complex(expr_ty exp)
427 : : {
428 : : assert(exp->kind == BinOp_kind);
429 : 0 : expr_ty left = exp->v.BinOp.left;
430 : 0 : expr_ty right = exp->v.BinOp.right;
431 : : // Ensure op is addition or subtraction
432 [ # # # # ]: 0 : if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
433 : 0 : return 0;
434 : : }
435 : : // Check LHS is a real number (potentially signed)
436 [ # # # ]: 0 : switch (left->kind)
437 : : {
438 : 0 : case Constant_kind:
439 [ # # ]: 0 : if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
440 : 0 : return 0;
441 : : }
442 : 0 : break;
443 : 0 : case UnaryOp_kind:
444 [ # # ]: 0 : if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
445 : 0 : return 0;
446 : : }
447 : 0 : break;
448 : 0 : default:
449 : 0 : return 0;
450 : : }
451 : : // Check RHS is an imaginary number (no separate sign allowed)
452 [ # # ]: 0 : switch (right->kind)
453 : : {
454 : 0 : case Constant_kind:
455 [ # # ]: 0 : if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
456 : 0 : return 0;
457 : : }
458 : 0 : break;
459 : 0 : default:
460 : 0 : return 0;
461 : : }
462 : 0 : return 1;
463 : : }
464 : :
465 : : static int
466 : 11 : validate_pattern_match_value(struct validator *state, expr_ty exp)
467 : : {
468 [ + + ]: 11 : if (!validate_expr(state, exp, Load)) {
469 : 2 : return 0;
470 : : }
471 : :
472 [ + - - - : 9 : switch (exp->kind)
- + ]
473 : : {
474 : 8 : case Constant_kind:
475 : : /* Ellipsis and immutable sequences are not allowed.
476 : : For True, False and None, MatchSingleton() should
477 : : be used */
478 [ - + ]: 8 : if (!validate_expr(state, exp, Load)) {
479 : 0 : return 0;
480 : : }
481 : 8 : PyObject *literal = exp->v.Constant.value;
482 [ + + + - : 13 : if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) ||
+ - ]
483 [ + - + + ]: 15 : PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) ||
484 : 5 : PyUnicode_CheckExact(literal)) {
485 : 5 : return 1;
486 : : }
487 : 3 : PyErr_SetString(PyExc_ValueError,
488 : : "unexpected constant inside of a literal pattern");
489 : 3 : return 0;
490 : 0 : case Attribute_kind:
491 : : // Constants and attribute lookups are always permitted
492 : 0 : return 1;
493 : 0 : case UnaryOp_kind:
494 : : // Negated numbers are permitted (whether real or imaginary)
495 : : // Compiler will complain if AST folding doesn't create a constant
496 [ # # ]: 0 : if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
497 : 0 : return 1;
498 : : }
499 : 0 : break;
500 : 0 : case BinOp_kind:
501 : : // Complex literals are permitted
502 : : // Compiler will complain if AST folding doesn't create a constant
503 [ # # ]: 0 : if (ensure_literal_complex(exp)) {
504 : 0 : return 1;
505 : : }
506 : 0 : break;
507 : 0 : case JoinedStr_kind:
508 : : // Handled in the later stages
509 : 0 : return 1;
510 : 1 : default:
511 : 1 : break;
512 : : }
513 : 1 : PyErr_SetString(PyExc_ValueError,
514 : : "patterns may only match literals and attribute lookups");
515 : 1 : return 0;
516 : : }
517 : :
518 : : static int
519 : 10 : validate_capture(PyObject *name)
520 : : {
521 [ + + ]: 10 : if (_PyUnicode_EqualToASCIIString(name, "_")) {
522 : 3 : PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
523 : 3 : return 0;
524 : : }
525 : 7 : return validate_name(name);
526 : : }
527 : :
528 : : static int
529 : 48 : validate_pattern(struct validator *state, pattern_ty p, int star_ok)
530 : : {
531 [ - + - + : 48 : VALIDATE_POSITIONS(p);
- - - + -
- + - -
+ ]
532 : 48 : int ret = -1;
533 [ - + ]: 48 : if (++state->recursion_depth > state->recursion_limit) {
534 : 0 : PyErr_SetString(PyExc_RecursionError,
535 : : "maximum recursion depth exceeded during compilation");
536 : 0 : return 0;
537 : : }
538 [ + + + + : 48 : switch (p->kind) {
+ + + +
- ]
539 : 10 : case MatchValue_kind:
540 : 10 : ret = validate_pattern_match_value(state, p->v.MatchValue.value);
541 : 10 : break;
542 : 6 : case MatchSingleton_kind:
543 [ + + - + ]: 6 : ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value);
544 [ + + ]: 6 : if (!ret) {
545 : 5 : PyErr_SetString(PyExc_ValueError,
546 : : "MatchSingleton can only contain True, False and None");
547 : : }
548 : 6 : break;
549 : 5 : case MatchSequence_kind:
550 : 5 : ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1);
551 : 5 : break;
552 : 4 : case MatchMapping_kind:
553 [ + - + - : 4 : if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
+ + ]
554 : 1 : PyErr_SetString(PyExc_ValueError,
555 : : "MatchMapping doesn't have the same number of keys as patterns");
556 : 1 : ret = 0;
557 : 1 : break;
558 : : }
559 : :
560 [ + - + + ]: 3 : if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) {
561 : 2 : ret = 0;
562 : 2 : break;
563 : : }
564 : :
565 : 1 : asdl_expr_seq *keys = p->v.MatchMapping.keys;
566 [ + - + - ]: 2 : for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) {
567 : 2 : expr_ty key = asdl_seq_GET(keys, i);
568 [ + + ]: 2 : if (key->kind == Constant_kind) {
569 : 1 : PyObject *literal = key->v.Constant.value;
570 [ + - + - ]: 1 : if (literal == Py_None || PyBool_Check(literal)) {
571 : : /* validate_pattern_match_value will ensure the key
572 : : doesn't contain True, False and None but it is
573 : : syntactically valid, so we will pass those on in
574 : : a special case. */
575 : 1 : continue;
576 : : }
577 : : }
578 [ + - ]: 1 : if (!validate_pattern_match_value(state, key)) {
579 : 1 : ret = 0;
580 : 1 : break;
581 : : }
582 : : }
583 : :
584 : 1 : ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
585 : 1 : break;
586 : 10 : case MatchClass_kind:
587 [ + - + - : 10 : if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
+ + ]
588 : 2 : PyErr_SetString(PyExc_ValueError,
589 : : "MatchClass doesn't have the same number of keyword attributes as patterns");
590 : 2 : ret = 0;
591 : 2 : break;
592 : : }
593 [ - + ]: 8 : if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
594 : 0 : ret = 0;
595 : 0 : break;
596 : : }
597 : :
598 : 8 : expr_ty cls = p->v.MatchClass.cls;
599 : : while (1) {
600 [ + + ]: 13 : if (cls->kind == Name_kind) {
601 : 7 : break;
602 : : }
603 [ + + ]: 6 : else if (cls->kind == Attribute_kind) {
604 : 5 : cls = cls->v.Attribute.value;
605 : 5 : continue;
606 : : }
607 : : else {
608 : 1 : PyErr_SetString(PyExc_ValueError,
609 : : "MatchClass cls field can only contain Name or Attribute nodes.");
610 : 1 : ret = 0;
611 : 1 : break;
612 : : }
613 : : }
614 : :
615 [ + - + + ]: 8 : for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
616 : 1 : PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
617 [ + - ]: 1 : if (!validate_name(identifier)) {
618 : 1 : ret = 0;
619 : 1 : break;
620 : : }
621 : : }
622 : :
623 [ + + ]: 8 : if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
624 : 2 : ret = 0;
625 : 2 : break;
626 : : }
627 : :
628 : 6 : ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);
629 : 6 : break;
630 : 4 : case MatchStar_kind:
631 [ + + ]: 4 : if (!star_ok) {
632 : 2 : PyErr_SetString(PyExc_ValueError, "can't use MatchStar here");
633 : 2 : ret = 0;
634 : 2 : break;
635 : : }
636 [ + - - + ]: 2 : ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name);
637 : 2 : break;
638 : 6 : case MatchAs_kind:
639 [ + + + + ]: 6 : if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) {
640 : 2 : ret = 0;
641 : 2 : break;
642 : : }
643 [ + - ]: 4 : if (p->v.MatchAs.pattern == NULL) {
644 : 4 : ret = 1;
645 : : }
646 [ # # ]: 0 : else if (p->v.MatchAs.name == NULL) {
647 : 0 : PyErr_SetString(PyExc_ValueError,
648 : : "MatchAs must specify a target name if a pattern is given");
649 : 0 : ret = 0;
650 : : }
651 : : else {
652 : 0 : ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0);
653 : : }
654 : 4 : break;
655 : 3 : case MatchOr_kind:
656 [ + - + + ]: 3 : if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) {
657 : 2 : PyErr_SetString(PyExc_ValueError,
658 : : "MatchOr requires at least 2 patterns");
659 : 2 : ret = 0;
660 : 2 : break;
661 : : }
662 : 1 : ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0);
663 : 1 : break;
664 : : // No default case, so the compiler will emit a warning if new pattern
665 : : // kinds are added without being handled here
666 : : }
667 [ - + ]: 48 : if (ret < 0) {
668 : 0 : PyErr_SetString(PyExc_SystemError, "unexpected pattern");
669 : 0 : ret = 0;
670 : : }
671 : 48 : state->recursion_depth--;
672 : 48 : return ret;
673 : : }
674 : :
675 : : static int
676 : 47468 : _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
677 : : {
678 [ + - + + ]: 47468 : if (asdl_seq_LEN(seq))
679 : 47451 : return 1;
680 : 17 : PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
681 : 17 : return 0;
682 : : }
683 : : #define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)
684 : :
685 : : static int
686 : 21076 : validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
687 : : {
688 [ + + + + : 42150 : return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
+ + ]
689 : 21074 : validate_exprs(state, targets, ctx, 0);
690 : : }
691 : :
692 : : static int
693 : 24552 : validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
694 : : {
695 [ + + + + ]: 24552 : return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
696 : : }
697 : :
698 : : static int
699 : 69956 : validate_stmt(struct validator *state, stmt_ty stmt)
700 : : {
701 [ + + + + : 69956 : VALIDATE_POSITIONS(stmt);
- + + + +
- + + +
+ ]
702 : 69946 : int ret = -1;
703 : : Py_ssize_t i;
704 [ - + ]: 69946 : if (++state->recursion_depth > state->recursion_limit) {
705 : 0 : PyErr_SetString(PyExc_RecursionError,
706 : : "maximum recursion depth exceeded during compilation");
707 : 0 : return 0;
708 : : }
709 [ + + + + : 69946 : switch (stmt->kind) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ - ]
710 : 7392 : case FunctionDef_kind:
711 [ + + ]: 14783 : ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
712 [ + + ]: 14775 : validate_arguments(state, stmt->v.FunctionDef.args) &&
713 [ + + ]: 22167 : validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
714 [ + + + + ]: 7439 : (!stmt->v.FunctionDef.returns ||
715 : 56 : validate_expr(state, stmt->v.FunctionDef.returns, Load));
716 : 7392 : break;
717 : 829 : case ClassDef_kind:
718 [ + + ]: 1656 : ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
719 [ + + ]: 1653 : validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
720 [ + + + + ]: 2482 : validate_keywords(state, stmt->v.ClassDef.keywords) &&
721 : 825 : validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
722 : 829 : break;
723 : 7068 : case Return_kind:
724 [ + + + - ]: 7068 : ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
725 : 7068 : break;
726 : 223 : case Delete_kind:
727 : 223 : ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
728 : 223 : break;
729 : 20853 : case Assign_kind:
730 [ + + + + ]: 41701 : ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
731 : 20848 : validate_expr(state, stmt->v.Assign.value, Load);
732 : 20853 : break;
733 : 860 : case AugAssign_kind:
734 [ + + + + ]: 1719 : ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
735 : 859 : validate_expr(state, stmt->v.AugAssign.value, Load);
736 : 860 : break;
737 : 37 : case AnnAssign_kind:
738 [ + + ]: 37 : if (stmt->v.AnnAssign.target->kind != Name_kind &&
739 [ - + ]: 9 : stmt->v.AnnAssign.simple) {
740 : 0 : PyErr_SetString(PyExc_TypeError,
741 : : "AnnAssign with simple non-Name target");
742 : 0 : return 0;
743 : : }
744 : 37 : ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
745 [ + + + - ]: 48 : (!stmt->v.AnnAssign.value ||
746 [ + - + - ]: 85 : validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
747 : 37 : validate_expr(state, stmt->v.AnnAssign.annotation, Load);
748 : 37 : break;
749 : 1394 : case For_kind:
750 [ + + ]: 2787 : ret = validate_expr(state, stmt->v.For.target, Store) &&
751 [ + + ]: 2785 : validate_expr(state, stmt->v.For.iter, Load) &&
752 [ + + + + ]: 4179 : validate_body(state, stmt->v.For.body, "For") &&
753 : 1390 : validate_stmts(state, stmt->v.For.orelse);
754 : 1394 : break;
755 : 6 : case AsyncFor_kind:
756 [ + - ]: 12 : ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
757 [ + - ]: 12 : validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
758 [ + - + - ]: 18 : validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
759 : 6 : validate_stmts(state, stmt->v.AsyncFor.orelse);
760 : 6 : break;
761 : 445 : case While_kind:
762 [ + + ]: 889 : ret = validate_expr(state, stmt->v.While.test, Load) &&
763 [ + + + + ]: 889 : validate_body(state, stmt->v.While.body, "While") &&
764 : 443 : validate_stmts(state, stmt->v.While.orelse);
765 : 445 : break;
766 : 11158 : case If_kind:
767 [ + + ]: 22315 : ret = validate_expr(state, stmt->v.If.test, Load) &&
768 [ + + + + ]: 22315 : validate_body(state, stmt->v.If.body, "If") &&
769 : 11155 : validate_stmts(state, stmt->v.If.orelse);
770 : 11158 : break;
771 : 384 : case With_kind:
772 [ + + ]: 384 : if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
773 : 1 : return 0;
774 [ + - + + ]: 786 : for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
775 : 405 : withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
776 [ + + ]: 405 : if (!validate_expr(state, item->context_expr, Load) ||
777 [ + + + + ]: 404 : (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
778 : 2 : return 0;
779 : : }
780 : 381 : ret = validate_body(state, stmt->v.With.body, "With");
781 : 381 : break;
782 : 9 : case AsyncWith_kind:
783 [ - + ]: 9 : if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
784 : 0 : return 0;
785 [ + - + + ]: 21 : for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
786 : 12 : withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
787 [ + - ]: 12 : if (!validate_expr(state, item->context_expr, Load) ||
788 [ + + - + ]: 12 : (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
789 : 0 : return 0;
790 : : }
791 : 9 : ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
792 : 9 : break;
793 : 29 : case Match_kind:
794 [ + - ]: 29 : if (!validate_expr(state, stmt->v.Match.subject, Load)
795 [ - + ]: 29 : || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
796 : 0 : return 0;
797 : : }
798 [ + - + + ]: 39 : for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
799 : 33 : match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
800 [ + + ]: 33 : if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
801 [ + + + - ]: 10 : || (m->guard && !validate_expr(state, m->guard, Load))
802 [ - + ]: 10 : || !validate_body(state, m->body, "match_case")) {
803 : 23 : return 0;
804 : : }
805 : : }
806 : 6 : ret = 1;
807 : 6 : break;
808 : 2311 : case Raise_kind:
809 [ + + ]: 2311 : if (stmt->v.Raise.exc) {
810 [ + + ]: 4293 : ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
811 [ + + + + ]: 2146 : (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
812 : 2147 : break;
813 : : }
814 [ + + ]: 164 : if (stmt->v.Raise.cause) {
815 : 1 : PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
816 : 1 : return 0;
817 : : }
818 : 163 : ret = 1;
819 : 163 : break;
820 : 1470 : case Try_kind:
821 [ + + ]: 1470 : if (!validate_body(state, stmt->v.Try.body, "Try"))
822 : 2 : return 0;
823 [ + - + + ]: 1468 : if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
824 [ + - + + ]: 150 : !asdl_seq_LEN(stmt->v.Try.finalbody)) {
825 : 1 : PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
826 : 1 : return 0;
827 : : }
828 [ + - + + ]: 1467 : if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
829 [ + - + + ]: 149 : asdl_seq_LEN(stmt->v.Try.orelse)) {
830 : 1 : PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
831 : 1 : return 0;
832 : : }
833 [ + - + + ]: 2862 : for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
834 : 1398 : excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
835 [ - + - + : 1398 : VALIDATE_POSITIONS(handler);
- - - + -
- + + -
+ ]
836 [ + + + + ]: 2703 : if ((handler->v.ExceptHandler.type &&
837 [ + + ]: 2702 : !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
838 : 1397 : !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
839 : 2 : return 0;
840 : : }
841 [ + + + + ]: 1634 : ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
842 [ + - ]: 3098 : validate_stmts(state, stmt->v.Try.finalbody)) &&
843 [ + - + + : 1641 : (!asdl_seq_LEN(stmt->v.Try.orelse) ||
+ + ]
844 : 178 : validate_stmts(state, stmt->v.Try.orelse));
845 : 1464 : break;
846 : 14 : case TryStar_kind:
847 [ + + ]: 14 : if (!validate_body(state, stmt->v.TryStar.body, "TryStar"))
848 : 2 : return 0;
849 [ + - + + ]: 12 : if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
850 [ + - + + ]: 2 : !asdl_seq_LEN(stmt->v.TryStar.finalbody)) {
851 : 1 : PyErr_SetString(PyExc_ValueError, "TryStar has neither except handlers nor finalbody");
852 : 1 : return 0;
853 : : }
854 [ + - + + ]: 11 : if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
855 [ + - + - ]: 1 : asdl_seq_LEN(stmt->v.TryStar.orelse)) {
856 : 1 : PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
857 : 1 : return 0;
858 : : }
859 [ + - + + ]: 19 : for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
860 : 11 : excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
861 [ + + + + ]: 19 : if ((handler->v.ExceptHandler.type &&
862 [ + + ]: 18 : !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
863 : 10 : !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
864 : 2 : return 0;
865 : : }
866 [ + + + + ]: 10 : ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) ||
867 [ + - ]: 18 : validate_stmts(state, stmt->v.TryStar.finalbody)) &&
868 [ + - + + : 10 : (!asdl_seq_LEN(stmt->v.TryStar.orelse) ||
+ + ]
869 : 3 : validate_stmts(state, stmt->v.TryStar.orelse));
870 : 8 : break;
871 : 224 : case Assert_kind:
872 [ + + ]: 447 : ret = validate_expr(state, stmt->v.Assert.test, Load) &&
873 [ + + + + ]: 223 : (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
874 : 224 : break;
875 : 961 : case Import_kind:
876 : 961 : ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
877 : 961 : break;
878 : 371 : case ImportFrom_kind:
879 [ + + ]: 371 : if (stmt->v.ImportFrom.level < 0) {
880 : 1 : PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
881 : 1 : return 0;
882 : : }
883 : 370 : ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
884 : 370 : break;
885 : 66 : case Global_kind:
886 : 66 : ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
887 : 66 : break;
888 : 21 : case Nonlocal_kind:
889 : 21 : ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
890 : 21 : break;
891 : 12376 : case Expr_kind:
892 : 12376 : ret = validate_expr(state, stmt->v.Expr.value, Load);
893 : 12376 : break;
894 : 41 : case AsyncFunctionDef_kind:
895 [ + - ]: 82 : ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
896 [ + - ]: 82 : validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
897 [ + - ]: 123 : validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
898 [ - + - - ]: 41 : (!stmt->v.AsyncFunctionDef.returns ||
899 : 0 : validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
900 : 41 : break;
901 : 1404 : case Pass_kind:
902 : : case Break_kind:
903 : : case Continue_kind:
904 : 1404 : ret = 1;
905 : 1404 : break;
906 : : // No default case so compiler emits warning for unhandled cases
907 : : }
908 [ - + ]: 69906 : if (ret < 0) {
909 : 0 : PyErr_SetString(PyExc_SystemError, "unexpected statement");
910 : 0 : ret = 0;
911 : : }
912 : 69906 : state->recursion_depth--;
913 : 69906 : return ret;
914 : : }
915 : :
916 : : static int
917 : 38459 : validate_stmts(struct validator *state, asdl_stmt_seq *seq)
918 : : {
919 : : Py_ssize_t i;
920 [ + - + + ]: 108234 : for (i = 0; i < asdl_seq_LEN(seq); i++) {
921 : 69957 : stmt_ty stmt = asdl_seq_GET(seq, i);
922 [ + + ]: 69957 : if (stmt) {
923 [ + + ]: 69956 : if (!validate_stmt(state, stmt))
924 : 181 : return 0;
925 : : }
926 : : else {
927 : 1 : PyErr_SetString(PyExc_ValueError,
928 : : "None disallowed in statement list");
929 : 1 : return 0;
930 : : }
931 : : }
932 : 38277 : return 1;
933 : : }
934 : :
935 : : static int
936 : 94827 : validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
937 : : {
938 : : Py_ssize_t i;
939 [ + - + + ]: 192911 : for (i = 0; i < asdl_seq_LEN(exprs); i++) {
940 : 98117 : expr_ty expr = asdl_seq_GET(exprs, i);
941 [ + + ]: 98117 : if (expr) {
942 [ + + ]: 98052 : if (!validate_expr(state, expr, ctx))
943 : 21 : return 0;
944 : : }
945 [ + + ]: 65 : else if (!null_ok) {
946 : 12 : PyErr_SetString(PyExc_ValueError,
947 : : "None disallowed in expression list");
948 : 12 : return 0;
949 : : }
950 : :
951 : : }
952 : 94794 : return 1;
953 : : }
954 : :
955 : : static int
956 : 21 : validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
957 : : {
958 : : Py_ssize_t i;
959 [ + - + + ]: 28 : for (i = 0; i < asdl_seq_LEN(patterns); i++) {
960 : 15 : pattern_ty pattern = asdl_seq_GET(patterns, i);
961 [ + + ]: 15 : if (!validate_pattern(state, pattern, star_ok)) {
962 : 8 : return 0;
963 : : }
964 : : }
965 : 13 : return 1;
966 : : }
967 : :
968 : :
969 : : /* See comments in symtable.c. */
970 : : #define COMPILER_STACK_FRAME_SCALE 3
971 : :
972 : : int
973 : 679 : _PyAST_Validate(mod_ty mod)
974 : : {
975 : 679 : int res = -1;
976 : : struct validator state;
977 : : PyThreadState *tstate;
978 : 679 : int recursion_limit = Py_GetRecursionLimit();
979 : : int starting_recursion_depth;
980 : :
981 : : /* Setup recursion depth check counters */
982 : 679 : tstate = _PyThreadState_GET();
983 [ - + ]: 679 : if (!tstate) {
984 : 0 : return 0;
985 : : }
986 : : /* Be careful here to prevent overflow. */
987 : 679 : int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining;
988 : 679 : starting_recursion_depth = (recursion_depth< INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
989 [ + - ]: 679 : recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth;
990 : 679 : state.recursion_depth = starting_recursion_depth;
991 : 679 : state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
992 [ + - ]: 679 : recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
993 : :
994 [ + + + - : 679 : switch (mod->kind) {
- ]
995 : 568 : case Module_kind:
996 : 568 : res = validate_stmts(&state, mod->v.Module.body);
997 : 568 : break;
998 : 2 : case Interactive_kind:
999 : 2 : res = validate_stmts(&state, mod->v.Interactive.body);
1000 : 2 : break;
1001 : 109 : case Expression_kind:
1002 : 109 : res = validate_expr(&state, mod->v.Expression.body, Load);
1003 : 109 : break;
1004 : 0 : case FunctionType_kind:
1005 [ # # # # ]: 0 : res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
1006 : 0 : validate_expr(&state, mod->v.FunctionType.returns, Load);
1007 : 0 : break;
1008 : : // No default case so compiler emits warning for unhandled cases
1009 : : }
1010 : :
1011 [ - + ]: 679 : if (res < 0) {
1012 : 0 : PyErr_SetString(PyExc_SystemError, "impossible module node");
1013 : 0 : return 0;
1014 : : }
1015 : :
1016 : : /* Check that the recursion depth counting balanced correctly */
1017 [ + + - + ]: 679 : if (res && state.recursion_depth != starting_recursion_depth) {
1018 : 0 : PyErr_Format(PyExc_SystemError,
1019 : : "AST validator recursion depth mismatch (before=%d, after=%d)",
1020 : : starting_recursion_depth, state.recursion_depth);
1021 : 0 : return 0;
1022 : : }
1023 : 679 : return res;
1024 : : }
1025 : :
1026 : : PyObject *
1027 : 936126 : _PyAST_GetDocString(asdl_stmt_seq *body)
1028 : : {
1029 [ + + - + ]: 936126 : if (!asdl_seq_LEN(body)) {
1030 : 1358 : return NULL;
1031 : : }
1032 : 934768 : stmt_ty st = asdl_seq_GET(body, 0);
1033 [ + + ]: 934768 : if (st->kind != Expr_kind) {
1034 : 646079 : return NULL;
1035 : : }
1036 : 288689 : expr_ty e = st->v.Expr.value;
1037 [ + + + + ]: 288689 : if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
1038 : 202396 : return e->v.Constant.value;
1039 : : }
1040 : 86293 : return NULL;
1041 : : }
|