| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* Write Python objects to files and read them back. | 2 /* Write Python objects to files and read them back. |
| 3 This is intended for writing and reading compiled Python code only; | 3 This is intended for writing and reading compiled Python code only; |
| 4 a true persistent storage facility would be much harder, since | 4 a true persistent storage facility would be much harder, since |
| 5 it would have to take circular links and sharing into account. */ | 5 it would have to take circular links and sharing into account. */ |
| 6 | 6 |
| 7 #define PY_SSIZE_T_CLEAN | 7 #define PY_SSIZE_T_CLEAN |
| 8 | 8 |
| 9 #include "Python.h" | 9 #include "Python.h" |
| 10 #include "longintrepr.h" | 10 #include "longintrepr.h" |
| 11 #include "code.h" | 11 #include "code.h" |
| 12 #include "marshal.h" | 12 #include "marshal.h" |
| 13 | 13 |
| 14 #define ABS(x) ((x) < 0 ? -(x) : (x)) | |
| 15 | |
| 14 /* High water mark to determine when the marshalled object is dangerously deep | 16 /* High water mark to determine when the marshalled object is dangerously deep |
| 15 * and risks coring the interpreter. When the object stack gets this deep, | 17 * and risks coring the interpreter. When the object stack gets this deep, |
| 16 * raise an exception instead of continuing. | 18 * raise an exception instead of continuing. |
| 17 * On Windows debug builds, reduce this value. | 19 * On Windows debug builds, reduce this value. |
| 18 */ | 20 */ |
| 19 #if defined(MS_WINDOWS) && defined(_DEBUG) | 21 #if defined(MS_WINDOWS) && defined(_DEBUG) |
| 20 #define MAX_MARSHAL_STACK_DEPTH 1500 | 22 #define MAX_MARSHAL_STACK_DEPTH 1500 |
| 21 #else | 23 #else |
| 22 #define MAX_MARSHAL_STACK_DEPTH 2000 | 24 #define MAX_MARSHAL_STACK_DEPTH 2000 |
| 23 #endif | 25 #endif |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 | 117 |
| 116 #if SIZEOF_LONG > 4 | 118 #if SIZEOF_LONG > 4 |
| 117 static void | 119 static void |
| 118 w_long64(long x, WFILE *p) | 120 w_long64(long x, WFILE *p) |
| 119 { | 121 { |
| 120 w_long(x, p); | 122 w_long(x, p); |
| 121 w_long(x>>32, p); | 123 w_long(x>>32, p); |
| 122 } | 124 } |
| 123 #endif | 125 #endif |
| 124 | 126 |
| 127 /* We assume that Python longs are stored internally in base some power of | |
| 128 2**15; for the sake of portability we'll always read and write them in base | |
| 129 exactly 2**15. */ | |
| 130 | |
| 131 #define PyLong_MARSHAL_SHIFT 15 | |
| 132 #define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT) | |
| 133 #define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1) | |
| 134 #if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0 | |
| 135 #error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT" | |
| 136 #endif | |
| 137 #define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT) | |
| 138 | |
| 139 static void | |
| 140 w_PyLong(const PyLongObject *ob, WFILE *p) | |
| 141 { | |
| 142 Py_ssize_t i, j, n, l; | |
| 143 digit d; | |
| 144 | |
| 145 w_byte(TYPE_LONG, p); | |
| 146 if (Py_SIZE(ob) == 0) { | |
| 147 w_long((long)0, p); | |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 /* set l to number of base PyLong_MARSHAL_BASE digits */ | |
| 152 n = ABS(Py_SIZE(ob)); | |
| 153 l = (n-1) * PyLong_MARSHAL_RATIO; | |
| 154 d = ob->ob_digit[n-1]; | |
| 155 assert(d != 0); /* a PyLong is always normalized */ | |
| 156 do { | |
| 157 d >>= PyLong_MARSHAL_SHIFT; | |
| 158 l++; | |
| 159 } while (d != 0); | |
| 160 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p); | |
|
Martin v. Löwis
2009/02/17 22:39:18
This needs to deal with overflow (sizeof(size_t) >
dickinsm
2009/02/18 17:06:33
Hmm. It looks as though there are many places in
Martin v. Löwis
2009/02/18 21:27:04
Ok, so I'd waive this for this patch; please do cr
dickinsm
2009/02/19 09:42:15
Done.
http://bugs.python.org/issue5308
| |
| 161 | |
| 162 for (i=0; i < n-1; i++) { | |
| 163 d = ob->ob_digit[i]; | |
| 164 for (j=0; j < PyLong_MARSHAL_RATIO; j++) { | |
| 165 w_short(d & PyLong_MARSHAL_MASK, p); | |
| 166 d >>= PyLong_MARSHAL_SHIFT; | |
| 167 } | |
| 168 assert (d == 0); | |
| 169 } | |
| 170 d = ob->ob_digit[n-1]; | |
| 171 do { | |
| 172 w_short(d & PyLong_MARSHAL_MASK, p); | |
| 173 d >>= PyLong_MARSHAL_SHIFT; | |
| 174 } while (d != 0); | |
| 175 } | |
| 176 | |
| 125 static void | 177 static void |
| 126 w_object(PyObject *v, WFILE *p) | 178 w_object(PyObject *v, WFILE *p) |
| 127 { | 179 { |
| 128 Py_ssize_t i, n; | 180 Py_ssize_t i, n; |
| 129 | 181 |
| 130 p->depth++; | 182 p->depth++; |
| 131 | 183 |
| 132 if (p->depth > MAX_MARSHAL_STACK_DEPTH) { | 184 if (p->depth > MAX_MARSHAL_STACK_DEPTH) { |
| 133 p->error = 2; | 185 p->error = 2; |
| 134 } | 186 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 148 w_byte(TYPE_FALSE, p); | 200 w_byte(TYPE_FALSE, p); |
| 149 } | 201 } |
| 150 else if (v == Py_True) { | 202 else if (v == Py_True) { |
| 151 w_byte(TYPE_TRUE, p); | 203 w_byte(TYPE_TRUE, p); |
| 152 } | 204 } |
| 153 else if (PyLong_CheckExact(v)) { | 205 else if (PyLong_CheckExact(v)) { |
| 154 long x = PyLong_AsLong(v); | 206 long x = PyLong_AsLong(v); |
| 155 if ((x == -1) && PyErr_Occurred()) { | 207 if ((x == -1) && PyErr_Occurred()) { |
| 156 PyLongObject *ob = (PyLongObject *)v; | 208 PyLongObject *ob = (PyLongObject *)v; |
| 157 PyErr_Clear(); | 209 PyErr_Clear(); |
| 158 » » » w_byte(TYPE_LONG, p); | 210 » » » w_PyLong(ob, p); |
| 159 » » » n = Py_SIZE(ob); | 211 » » } |
| 160 » » » w_long((long)n, p); | |
| 161 » » » if (n < 0) | |
| 162 » » » » n = -n; | |
| 163 » » » for (i = 0; i < n; i++) | |
| 164 » » » » w_short(ob->ob_digit[i], p); | |
| 165 » » }· | |
| 166 else { | 212 else { |
| 167 #if SIZEOF_LONG > 4 | 213 #if SIZEOF_LONG > 4 |
| 168 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31); | 214 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31); |
| 169 if (y && y != -1) { | 215 if (y && y != -1) { |
| 170 w_byte(TYPE_INT64, p); | 216 w_byte(TYPE_INT64, p); |
| 171 w_long64(x, p); | 217 w_long64(x, p); |
| 172 } | 218 } |
| 173 else | 219 else |
| 174 #endif | 220 #endif |
| 175 { | 221 { |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 } | 520 } |
| 475 else { | 521 else { |
| 476 memcpy(buf, &hi4, 4); | 522 memcpy(buf, &hi4, 4); |
| 477 memcpy(buf+4, &lo4, 4); | 523 memcpy(buf+4, &lo4, 4); |
| 478 } | 524 } |
| 479 return _PyLong_FromByteArray(buf, 8, is_little_endian, 1); | 525 return _PyLong_FromByteArray(buf, 8, is_little_endian, 1); |
| 480 #endif | 526 #endif |
| 481 } | 527 } |
| 482 | 528 |
| 483 static PyObject * | 529 static PyObject * |
| 530 r_PyLong(RFILE *p) | |
| 531 { | |
| 532 PyLongObject *ob; | |
| 533 int size, i, j, md; | |
| 534 long n; | |
| 535 digit d; | |
| 536 | |
| 537 n = r_long(p); | |
| 538 if (n == 0) | |
| 539 return (PyObject *)_PyLong_New(0); | |
| 540 if (n < -INT_MAX || n > INT_MAX) | |
|
Martin v. Löwis
2009/02/17 22:39:18
I think this is obsolete now; longs can have up to
dickinsm
2009/02/18 17:06:33
Agreed. Again, this needs to be fixed throughout m
| |
| 541 goto bad_data; | |
| 542 | |
| 543 size = 1 + (ABS(n)-1) / PyLong_MARSHAL_RATIO; | |
| 544 ob = _PyLong_New(size); | |
| 545 if (ob == NULL) | |
| 546 return NULL; | |
| 547 Py_SIZE(ob) = n > 0 ? size : -size; | |
| 548 | |
| 549 for (i = 0; i < size-1; i++) { | |
| 550 d = 0; | |
| 551 for (j=0; j < PyLong_MARSHAL_RATIO; j++) { | |
| 552 md = r_short(p); | |
| 553 if (md < 0 || md > PyLong_MARSHAL_BASE) { | |
| 554 Py_DECREF(ob); | |
| 555 goto bad_data; | |
| 556 } | |
| 557 d += (digit)md << j*PyLong_MARSHAL_SHIFT; | |
| 558 } | |
| 559 ob->ob_digit[i] = d; | |
| 560 } | |
| 561 d = 0; | |
| 562 for (j=0; j < (ABS(n)-1)%PyLong_MARSHAL_RATIO + 1; j++) { | |
| 563 md = r_short(p); | |
| 564 if (md < 0 || md > PyLong_MARSHAL_BASE) { | |
| 565 Py_DECREF(ob); | |
| 566 goto bad_data; | |
| 567 } | |
| 568 d += (digit)md << (j*PyLong_MARSHAL_SHIFT); | |
| 569 } | |
| 570 ob->ob_digit[size-1] = d; | |
| 571 return (PyObject *)ob; | |
| 572 bad_data: | |
| 573 PyErr_SetString(PyExc_ValueError, "bad marshal data"); | |
| 574 return NULL; | |
| 575 } | |
| 576 | |
| 577 | |
| 578 static PyObject * | |
| 484 r_object(RFILE *p) | 579 r_object(RFILE *p) |
| 485 { | 580 { |
| 486 /* NULL is a valid return value, it does not necessarily means that | 581 /* NULL is a valid return value, it does not necessarily means that |
| 487 an exception is set. */ | 582 an exception is set. */ |
| 488 PyObject *v, *v2; | 583 PyObject *v, *v2; |
| 489 long i, n; | 584 long i, n; |
| 490 int type = r_byte(p); | 585 int type = r_byte(p); |
| 491 PyObject *retval; | 586 PyObject *retval; |
| 492 | 587 |
| 493 p->depth++; | 588 p->depth++; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 537 | 632 |
| 538 case TYPE_INT: | 633 case TYPE_INT: |
| 539 retval = PyLong_FromLong(r_long(p)); | 634 retval = PyLong_FromLong(r_long(p)); |
| 540 break; | 635 break; |
| 541 | 636 |
| 542 case TYPE_INT64: | 637 case TYPE_INT64: |
| 543 retval = r_long64(p); | 638 retval = r_long64(p); |
| 544 break; | 639 break; |
| 545 | 640 |
| 546 case TYPE_LONG: | 641 case TYPE_LONG: |
| 547 » » { | 642 » » retval = r_PyLong(p); |
| 548 » » » int size; | 643 » » break; |
| 549 » » » PyLongObject *ob; | |
| 550 » » » n = r_long(p); | |
| 551 » » » if (n < -INT_MAX || n > INT_MAX) { | |
| 552 » » » » PyErr_SetString(PyExc_ValueError, | |
| 553 » » » » » » "bad marshal data"); | |
| 554 » » » » retval = NULL; | |
| 555 » » » » break; | |
| 556 » » » } | |
| 557 » » » size = n<0 ? -n : n; | |
| 558 » » » ob = _PyLong_New(size); | |
| 559 » » » if (ob == NULL) { | |
| 560 » » » » retval = NULL; | |
| 561 » » » » break; | |
| 562 » » » } | |
| 563 » » » Py_SIZE(ob) = n; | |
| 564 » » » for (i = 0; i < size; i++) { | |
| 565 » » » » int digit = r_short(p); | |
| 566 » » » » if (digit < 0) { | |
| 567 » » » » » Py_DECREF(ob); | |
| 568 » » » » » PyErr_SetString(PyExc_ValueError, | |
| 569 » » » » » » » "bad marshal data"); | |
| 570 » » » » » ob = NULL; | |
| 571 » » » » » break; | |
| 572 » » » » } | |
| 573 » » » » if (ob != NULL) | |
| 574 » » » » » ob->ob_digit[i] = digit; | |
| 575 » » » } | |
| 576 » » » retval = (PyObject *)ob; | |
| 577 » » » break; | |
| 578 » » } | |
| 579 | 644 |
| 580 case TYPE_FLOAT: | 645 case TYPE_FLOAT: |
| 581 { | 646 { |
| 582 char buf[256]; | 647 char buf[256]; |
| 583 double dx; | 648 double dx; |
| 584 n = r_byte(p); | 649 n = r_byte(p); |
| 585 if (n == EOF || r_string(buf, (int)n, p) != n) { | 650 if (n == EOF || r_string(buf, (int)n, p) != n) { |
| 586 PyErr_SetString(PyExc_EOFError, | 651 PyErr_SetString(PyExc_EOFError, |
| 587 "EOF read where object expected"); | 652 "EOF read where object expected"); |
| 588 retval = NULL; | 653 retval = NULL; |
| (...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1211 | 1276 |
| 1212 PyMODINIT_FUNC | 1277 PyMODINIT_FUNC |
| 1213 PyMarshal_Init(void) | 1278 PyMarshal_Init(void) |
| 1214 { | 1279 { |
| 1215 PyObject *mod = PyModule_Create(&marshalmodule); | 1280 PyObject *mod = PyModule_Create(&marshalmodule); |
| 1216 if (mod == NULL) | 1281 if (mod == NULL) |
| 1217 return NULL; | 1282 return NULL; |
| 1218 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); | 1283 PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION); |
| 1219 return mod; | 1284 return mod; |
| 1220 } | 1285 } |
| OLD | NEW |