Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* Frame object implementation */ | 1 /* Frame object implementation */ |
2 | 2 |
3 #include "Python.h" | 3 #include "Python.h" |
4 | 4 |
5 #include "code.h" | 5 #include "code.h" |
6 #include "frameobject.h" | 6 #include "frameobject.h" |
7 #include "opcode.h" | 7 #include "opcode.h" |
8 #include "structmember.h" | 8 #include "structmember.h" |
9 | 9 |
10 #undef MIN | 10 #undef MIN |
11 #undef MAX | 11 #undef MAX |
12 #define MIN(a, b) ((a) < (b) ? (a) : (b)) | 12 #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
13 #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 13 #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
14 | 14 |
15 #define OFF(x) offsetof(PyFrameObject, x) | 15 #define OFF(x) offsetof(PyFrameObject, x) |
16 | 16 |
17 static PyMemberDef frame_memberlist[] = { | 17 static PyMemberDef frame_memberlist[] = { |
18 » {"f_back",» T_OBJECT,» OFF(f_back),» RO}, | 18 » {"f_back",» T_OBJECT,» OFF(f_back),» RO|RESTRICTED}, |
GvR
2009/02/25 17:42:41
Why make f_back restricted? Since all frame attrib
asktav
2009/02/25 21:00:57
Sure.
| |
19 » {"f_code",» T_OBJECT,» OFF(f_code),» RO}, | 19 » {"f_code",» T_OBJECT,» OFF(f_code),» RO|RESTRICTED}, |
GvR
2009/02/25 17:42:41
I'm still unclear why you'd want to hide access to
asktav
2009/02/25 21:00:57
See the comment on genobject.c
| |
20 » {"f_builtins",» T_OBJECT,» OFF(f_builtins),RO}, | 20 » {"f_builtins",» T_OBJECT,» OFF(f_builtins),RO|RESTRICTED}, |
21 » {"f_globals",» T_OBJECT,» OFF(f_globals),»RO}, | 21 » {"f_globals",» T_OBJECT,» OFF(f_globals),»RO|RESTRICTED}, |
22 » {"f_lasti",» T_INT,» » OFF(f_lasti),» RO}, | 22 » {"f_lasti",» T_INT,» » OFF(f_lasti),» RO|RESTRICTED}, |
GvR
2009/02/25 17:42:41
Technically this isn't needed.
asktav
2009/02/25 21:00:57
Sure.
| |
23 {NULL} /* Sentinel */ | 23 {NULL} /* Sentinel */ |
24 }; | 24 }; |
25 | 25 |
26 static int | |
27 restricted(void) | |
28 { | |
29 if (!PyEval_GetRestricted()) | |
30 return 0; | |
31 PyErr_SetString(PyExc_RuntimeError, | |
32 "Frame attributes are not accessible in restricted mode."); | |
33 return 1; | |
34 } | |
35 | |
26 #define WARN_GET_SET(NAME) \ | 36 #define WARN_GET_SET(NAME) \ |
27 static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \ | 37 static PyObject * frame_get_ ## NAME(PyFrameObject *f) { \ |
28 if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \ | 38 if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \ |
29 return NULL; \ | 39 return NULL; \ |
40 if (restricted()) \ | |
41 return NULL; \ | |
30 if (f->NAME) { \ | 42 if (f->NAME) { \ |
31 Py_INCREF(f->NAME); \ | 43 Py_INCREF(f->NAME); \ |
32 return f->NAME; \ | 44 return f->NAME; \ |
33 } \ | 45 } \ |
34 Py_RETURN_NONE; \ | 46 Py_RETURN_NONE; \ |
35 } \ | 47 } \ |
36 static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \ | 48 static int frame_set_ ## NAME(PyFrameObject *f, PyObject *new) { \ |
37 if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \ | 49 if (PyErr_WarnPy3k(#NAME " has been removed in 3.x", 2) < 0) \ |
38 return -1; \ | 50 return -1; \ |
51 if (restricted()) \ | |
52 return -1; \ | |
39 if (f->NAME) { \ | 53 if (f->NAME) { \ |
40 Py_CLEAR(f->NAME); \ | 54 Py_CLEAR(f->NAME); \ |
41 } \ | 55 } \ |
42 if (new == Py_None) \ | 56 if (new == Py_None) \ |
43 new = NULL; \ | 57 new = NULL; \ |
44 Py_XINCREF(new); \ | 58 Py_XINCREF(new); \ |
45 f->NAME = new; \ | 59 f->NAME = new; \ |
46 return 0; \ | 60 return 0; \ |
47 } | 61 } |
48 | 62 |
49 | 63 |
50 WARN_GET_SET(f_exc_traceback) | 64 WARN_GET_SET(f_exc_traceback) |
51 WARN_GET_SET(f_exc_type) | 65 WARN_GET_SET(f_exc_type) |
52 WARN_GET_SET(f_exc_value) | 66 WARN_GET_SET(f_exc_value) |
53 | 67 |
54 | 68 |
55 static PyObject * | 69 static PyObject * |
56 frame_getlocals(PyFrameObject *f, void *closure) | 70 frame_getlocals(PyFrameObject *f, void *closure) |
57 { | 71 { |
72 if (restricted()) | |
73 return NULL; | |
58 PyFrame_FastToLocals(f); | 74 PyFrame_FastToLocals(f); |
59 Py_INCREF(f->f_locals); | 75 Py_INCREF(f->f_locals); |
60 return f->f_locals; | 76 return f->f_locals; |
61 } | 77 } |
62 | 78 |
63 static PyObject * | 79 static PyObject * |
64 frame_getlineno(PyFrameObject *f, void *closure) | 80 frame_getlineno(PyFrameObject *f, void *closure) |
65 { | 81 { |
66 int lineno; | 82 int lineno; |
67 | 83 |
84 if (restricted()) | |
85 return NULL; | |
GvR
2009/02/25 17:42:41
The line number would be useful, and I don't see h
asktav
2009/02/25 21:00:57
Sure.
| |
86 | |
68 if (f->f_trace) | 87 if (f->f_trace) |
69 lineno = f->f_lineno; | 88 lineno = f->f_lineno; |
70 else | 89 else |
71 lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); | 90 lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); |
72 | 91 |
73 return PyInt_FromLong(lineno); | 92 return PyInt_FromLong(lineno); |
74 } | 93 } |
75 | 94 |
76 /* Setter for f_lineno - you can set f_lineno from within a trace function in | 95 /* Setter for f_lineno - you can set f_lineno from within a trace function in |
77 * order to jump to a given line of code, subject to some restrictions. Most | 96 * order to jump to a given line of code, subject to some restrictions. Most |
(...skipping 28 matching lines...) Expand all Loading... | |
106 int delta_iblock = 0; /* (ditto) */ | 125 int delta_iblock = 0; /* (ditto) */ |
107 int min_delta_iblock = 0; /* (ditto) */ | 126 int min_delta_iblock = 0; /* (ditto) */ |
108 int min_iblock = 0; /* (ditto) */ | 127 int min_iblock = 0; /* (ditto) */ |
109 int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */ | 128 int f_lasti_setup_addr = 0; /* Policing no-jump-into-finally */ |
110 int new_lasti_setup_addr = 0; /* (ditto) */ | 129 int new_lasti_setup_addr = 0; /* (ditto) */ |
111 int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ | 130 int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ |
112 int in_finally[CO_MAXBLOCKS]; /* (ditto) */ | 131 int in_finally[CO_MAXBLOCKS]; /* (ditto) */ |
113 int blockstack_top = 0; /* (ditto) */ | 132 int blockstack_top = 0; /* (ditto) */ |
114 unsigned char setup_op = 0; /* (ditto) */ | 133 unsigned char setup_op = 0; /* (ditto) */ |
115 | 134 |
135 if (restricted()) | |
136 return -1; | |
137 | |
116 /* f_lineno must be an integer. */ | 138 /* f_lineno must be an integer. */ |
117 if (!PyInt_Check(p_new_lineno)) { | 139 if (!PyInt_Check(p_new_lineno)) { |
118 PyErr_SetString(PyExc_ValueError, | 140 PyErr_SetString(PyExc_ValueError, |
119 "lineno must be an integer"); | 141 "lineno must be an integer"); |
120 return -1; | 142 return -1; |
121 } | 143 } |
122 | 144 |
123 /* You can only do this from within a trace function, not via | 145 /* You can only do this from within a trace function, not via |
124 * _getframe or similar hackery. */ | 146 * _getframe or similar hackery. */ |
125 if (!f->f_trace) | 147 if (!f->f_trace) |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 f->f_lineno = new_lineno; | 355 f->f_lineno = new_lineno; |
334 f->f_lasti = new_lasti; | 356 f->f_lasti = new_lasti; |
335 return 0; | 357 return 0; |
336 } | 358 } |
337 | 359 |
338 static PyObject * | 360 static PyObject * |
339 frame_gettrace(PyFrameObject *f, void *closure) | 361 frame_gettrace(PyFrameObject *f, void *closure) |
340 { | 362 { |
341 PyObject* trace = f->f_trace; | 363 PyObject* trace = f->f_trace; |
342 | 364 |
365 if (restricted()) | |
366 return NULL; | |
367 | |
343 if (trace == NULL) | 368 if (trace == NULL) |
344 trace = Py_None; | 369 trace = Py_None; |
345 | 370 |
346 Py_INCREF(trace); | 371 Py_INCREF(trace); |
347 | 372 |
348 return trace; | 373 return trace; |
349 } | 374 } |
350 | 375 |
351 static int | 376 static int |
352 frame_settrace(PyFrameObject *f, PyObject* v, void *closure) | 377 frame_settrace(PyFrameObject *f, PyObject* v, void *closure) |
353 { | 378 { |
354 /* We rely on f_lineno being accurate when f_trace is set. */ | 379 /* We rely on f_lineno being accurate when f_trace is set. */ |
355 | 380 |
356 PyObject* old_value = f->f_trace; | 381 PyObject* old_value = f->f_trace; |
357 | 382 |
383 if (restricted()) | |
384 return -1; | |
385 | |
358 Py_XINCREF(v); | 386 Py_XINCREF(v); |
359 f->f_trace = v; | 387 f->f_trace = v; |
360 | 388 |
361 if (v != NULL) | 389 if (v != NULL) |
362 f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); | 390 f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); |
363 | 391 |
364 Py_XDECREF(old_value); | 392 Py_XDECREF(old_value); |
365 | 393 |
366 return 0; | 394 return 0; |
367 } | 395 } |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
962 return freelist_size; | 990 return freelist_size; |
963 } | 991 } |
964 | 992 |
965 void | 993 void |
966 PyFrame_Fini(void) | 994 PyFrame_Fini(void) |
967 { | 995 { |
968 (void)PyFrame_ClearFreeList(); | 996 (void)PyFrame_ClearFreeList(); |
969 Py_XDECREF(builtin_object); | 997 Py_XDECREF(builtin_object); |
970 builtin_object = NULL; | 998 builtin_object = NULL; |
971 } | 999 } |
OLD | NEW |