| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3fb7c60 commit 8bf6904
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Improve error handling when read :mod:`marshal` data. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -751,23 +751,28 @@ r_string(Py_ssize_t n, RFILE *p) | |||
| 751 | 751 | static int | |
| 752 | 752 | r_byte(RFILE *p) | |
| 753 | 753 | { | |
| 754 | - int c = EOF; | ||
| 755 | - | ||
| 756 | 754 | if (p->ptr != NULL) { | |
| 757 | - if (p->ptr < p->end) | ||
| 758 | - c = (unsigned char) *p->ptr++; | ||
| 759 | - return c; | ||
| 755 | + if (p->ptr < p->end) { | ||
| 756 | + return (unsigned char) *p->ptr++; | ||
| 757 | + } | ||
| 760 | 758 | } | |
| 761 | - if (!p->readable) { | ||
| 759 | + else if (!p->readable) { | ||
| 762 | 760 | assert(p->fp); | |
| 763 | - c = getc(p->fp); | ||
| 761 | + int c = getc(p->fp); | ||
| 762 | + if (c != EOF) { | ||
| 763 | + return c; | ||
| 764 | + } | ||
| 764 | 765 | } | |
| 765 | 766 | else { | |
| 766 | 767 | const char *ptr = r_string(1, p); | |
| 767 | - if (ptr != NULL) | ||
| 768 | - c = *(const unsigned char *) ptr; | ||
| 768 | + if (ptr != NULL) { | ||
| 769 | + return *(const unsigned char *) ptr; | ||
| 770 | + } | ||
| 771 | + return EOF; | ||
| 769 | 772 | } | |
| 770 | - return c; | ||
| 773 | + PyErr_SetString(PyExc_EOFError, | ||
| 774 | + "EOF read where not expected"); | ||
| 775 | + return EOF; | ||
| 771 | 776 | } | |
| 772 | 777 | ||
| 773 | 778 | static int | |
@@ -828,10 +833,11 @@ r_PyLong(RFILE *p) | |||
| 828 | 833 | digit d; | |
| 829 | 834 | ||
| 830 | 835 | n = r_long(p); | |
| 831 | - if (PyErr_Occurred()) | ||
| 832 | - return NULL; | ||
| 833 | 836 | if (n == 0) | |
| 834 | 837 | return (PyObject *)_PyLong_New(0); | |
| 838 | + if (n == -1 && PyErr_Occurred()) { | ||
| 839 | + return NULL; | ||
| 840 | + } | ||
| 835 | 841 | if (n < -SIZE32_MAX || n > SIZE32_MAX) { | |
| 836 | 842 | PyErr_SetString(PyExc_ValueError, | |
| 837 | 843 | "bad marshal data (long size out of range)"); | |
@@ -850,10 +856,6 @@ r_PyLong(RFILE *p) | |||
| 850 | 856 | d = 0; | |
| 851 | 857 | for (j=0; j < PyLong_MARSHAL_RATIO; j++) { | |
| 852 | 858 | md = r_short(p); | |
| 853 | - if (PyErr_Occurred()) { | ||
| 854 | - Py_DECREF(ob); | ||
| 855 | - return NULL; | ||
| 856 | - } | ||
| 857 | 859 | if (md < 0 || md > PyLong_MARSHAL_BASE) | |
| 858 | 860 | goto bad_digit; | |
| 859 | 861 | d += (digit)md << j*PyLong_MARSHAL_SHIFT; | |
@@ -864,10 +866,6 @@ r_PyLong(RFILE *p) | |||
| 864 | 866 | d = 0; | |
| 865 | 867 | for (j=0; j < shorts_in_top_digit; j++) { | |
| 866 | 868 | md = r_short(p); | |
| 867 | - if (PyErr_Occurred()) { | ||
| 868 | - Py_DECREF(ob); | ||
| 869 | - return NULL; | ||
| 870 | - } | ||
| 871 | 869 | if (md < 0 || md > PyLong_MARSHAL_BASE) | |
| 872 | 870 | goto bad_digit; | |
| 873 | 871 | /* topmost marshal digit should be nonzero */ | |
@@ -879,18 +877,17 @@ r_PyLong(RFILE *p) | |||
| 879 | 877 | } | |
| 880 | 878 | d += (digit)md << j*PyLong_MARSHAL_SHIFT; | |
| 881 | 879 | } | |
| 882 | - if (PyErr_Occurred()) { | ||
| 883 | - Py_DECREF(ob); | ||
| 884 | - return NULL; | ||
| 885 | - } | ||
| 880 | + assert(!PyErr_Occurred()); | ||
| 886 | 881 | /* top digit should be nonzero, else the resulting PyLong won't be | |
| 887 | 882 | normalized */ | |
| 888 | 883 | ob->long_value.ob_digit[size-1] = d; | |
| 889 | 884 | return (PyObject *)ob; | |
| 890 | 885 | bad_digit: | |
| 891 | 886 | Py_DECREF(ob); | |
| 892 | - PyErr_SetString(PyExc_ValueError, | ||
| 893 | - "bad marshal data (digit out of range in long)"); | ||
| 887 | + if (!PyErr_Occurred()) { | ||
| 888 | + PyErr_SetString(PyExc_ValueError, | ||
| 889 | + "bad marshal data (digit out of range in long)"); | ||
| 890 | + } | ||
| 894 | 891 | return NULL; | |
| 895 | 892 | } | |
| 896 | 893 | ||
@@ -913,8 +910,6 @@ r_float_str(RFILE *p) | |||
| 913 | 910 | const char *ptr; | |
| 914 | 911 | n = r_byte(p); | |
| 915 | 912 | if (n == EOF) { | |
| 916 | - PyErr_SetString(PyExc_EOFError, | ||
| 917 | - "EOF read where object expected"); | ||
| 918 | 913 | return -1; | |
| 919 | 914 | } | |
| 920 | 915 | ptr = r_string(n, p); | |
@@ -992,8 +987,10 @@ r_object(RFILE *p) | |||
| 992 | 987 | PyObject *retval = NULL; | |
| 993 | 988 | ||
| 994 | 989 | if (code == EOF) { | |
| 995 | - PyErr_SetString(PyExc_EOFError, | ||
| 996 | - "EOF read where object expected"); | ||
| 990 | + if (PyErr_ExceptionMatches(PyExc_EOFError)) { | ||
| 991 | + PyErr_SetString(PyExc_EOFError, | ||
| 992 | + "EOF read where object expected"); | ||
| 993 | + } | ||
| 997 | 994 | return NULL; | |
| 998 | 995 | } | |
| 999 | 996 | ||
@@ -1040,7 +1037,10 @@ r_object(RFILE *p) | |||
| 1040 | 1037 | ||
| 1041 | 1038 | case TYPE_INT: | |
| 1042 | 1039 | n = r_long(p); | |
| 1043 | - retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n); | ||
| 1040 | + if (n == -1 && PyErr_Occurred()) { | ||
| 1041 | + break; | ||
| 1042 | + } | ||
| 1043 | + retval = PyLong_FromLong(n); | ||
| 1044 | 1044 | R_REF(retval); | |
| 1045 | 1045 | break; | |
| 1046 | 1046 | ||
@@ -1106,10 +1106,11 @@ r_object(RFILE *p) | |||
| 1106 | 1106 | { | |
| 1107 | 1107 | const char *ptr; | |
| 1108 | 1108 | n = r_long(p); | |
| 1109 | - if (PyErr_Occurred()) | ||
| 1110 | - break; | ||
| 1111 | 1109 | if (n < 0 || n > SIZE32_MAX) { | |
| 1112 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)"); | ||
| 1110 | + if (!PyErr_Occurred()) { | ||
| 1111 | + PyErr_SetString(PyExc_ValueError, | ||
| 1112 | + "bad marshal data (bytes object size out of range)"); | ||
| 1113 | + } | ||
| 1113 | 1114 | break; | |
| 1114 | 1115 | } | |
| 1115 | 1116 | v = PyBytes_FromStringAndSize((char *)NULL, n); | |
@@ -1131,10 +1132,11 @@ r_object(RFILE *p) | |||
| 1131 | 1132 | /* fall through */ | |
| 1132 | 1133 | case TYPE_ASCII: | |
| 1133 | 1134 | n = r_long(p); | |
| 1134 | - if (PyErr_Occurred()) | ||
| 1135 | - break; | ||
| 1136 | 1135 | if (n < 0 || n > SIZE32_MAX) { | |
| 1137 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); | ||
| 1136 | + if (!PyErr_Occurred()) { | ||
| 1137 | + PyErr_SetString(PyExc_ValueError, | ||
| 1138 | + "bad marshal data (string size out of range)"); | ||
| 1139 | + } | ||
| 1138 | 1140 | break; | |
| 1139 | 1141 | } | |
| 1140 | 1142 | goto _read_ascii; | |
@@ -1145,8 +1147,6 @@ r_object(RFILE *p) | |||
| 1145 | 1147 | case TYPE_SHORT_ASCII: | |
| 1146 | 1148 | n = r_byte(p); | |
| 1147 | 1149 | if (n == EOF) { | |
| 1148 | - PyErr_SetString(PyExc_EOFError, | ||
| 1149 | - "EOF read where object expected"); | ||
| 1150 | 1150 | break; | |
| 1151 | 1151 | } | |
| 1152 | 1152 | _read_ascii: | |
@@ -1173,10 +1173,11 @@ r_object(RFILE *p) | |||
| 1173 | 1173 | const char *buffer; | |
| 1174 | 1174 | ||
| 1175 | 1175 | n = r_long(p); | |
| 1176 | - if (PyErr_Occurred()) | ||
| 1177 | - break; | ||
| 1178 | 1176 | if (n < 0 || n > SIZE32_MAX) { | |
| 1179 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); | ||
| 1177 | + if (!PyErr_Occurred()) { | ||
| 1178 | + PyErr_SetString(PyExc_ValueError, | ||
| 1179 | + "bad marshal data (string size out of range)"); | ||
| 1180 | + } | ||
| 1180 | 1181 | break; | |
| 1181 | 1182 | } | |
| 1182 | 1183 | if (n != 0) { | |
@@ -1198,16 +1199,18 @@ r_object(RFILE *p) | |||
| 1198 | 1199 | } | |
| 1199 | 1200 | ||
| 1200 | 1201 | case TYPE_SMALL_TUPLE: | |
| 1201 | - n = (unsigned char) r_byte(p); | ||
| 1202 | - if (PyErr_Occurred()) | ||
| 1202 | + n = r_byte(p); | ||
| 1203 | + if (n == EOF) { | ||
| 1203 | 1204 | break; | |
| 1205 | + } | ||
| 1204 | 1206 | goto _read_tuple; | |
| 1205 | 1207 | case TYPE_TUPLE: | |
| 1206 | 1208 | n = r_long(p); | |
| 1207 | - if (PyErr_Occurred()) | ||
| 1208 | - break; | ||
| 1209 | 1209 | if (n < 0 || n > SIZE32_MAX) { | |
| 1210 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)"); | ||
| 1210 | + if (!PyErr_Occurred()) { | ||
| 1211 | + PyErr_SetString(PyExc_ValueError, | ||
| 1212 | + "bad marshal data (tuple size out of range)"); | ||
| 1213 | + } | ||
| 1211 | 1214 | break; | |
| 1212 | 1215 | } | |
| 1213 | 1216 | _read_tuple: | |
@@ -1232,10 +1235,11 @@ r_object(RFILE *p) | |||
| 1232 | 1235 | ||
| 1233 | 1236 | case TYPE_LIST: | |
| 1234 | 1237 | n = r_long(p); | |
| 1235 | - if (PyErr_Occurred()) | ||
| 1236 | - break; | ||
| 1237 | 1238 | if (n < 0 || n > SIZE32_MAX) { | |
| 1238 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)"); | ||
| 1239 | + if (!PyErr_Occurred()) { | ||
| 1240 | + PyErr_SetString(PyExc_ValueError, | ||
| 1241 | + "bad marshal data (list size out of range)"); | ||
| 1242 | + } | ||
| 1239 | 1243 | break; | |
| 1240 | 1244 | } | |
| 1241 | 1245 | v = PyList_New(n); | |
@@ -1288,10 +1292,11 @@ r_object(RFILE *p) | |||
| 1288 | 1292 | case TYPE_SET: | |
| 1289 | 1293 | case TYPE_FROZENSET: | |
| 1290 | 1294 | n = r_long(p); | |
| 1291 | - if (PyErr_Occurred()) | ||
| 1292 | - break; | ||
| 1293 | 1295 | if (n < 0 || n > SIZE32_MAX) { | |
| 1294 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); | ||
| 1296 | + if (!PyErr_Occurred()) { | ||
| 1297 | + PyErr_SetString(PyExc_ValueError, | ||
| 1298 | + "bad marshal data (set size out of range)"); | ||
| 1299 | + } | ||
| 1295 | 1300 | break; | |
| 1296 | 1301 | } | |
| 1297 | 1302 | ||
@@ -1368,20 +1373,20 @@ r_object(RFILE *p) | |||
| 1368 | 1373 | ||
| 1369 | 1374 | /* XXX ignore long->int overflows for now */ | |
| 1370 | 1375 | argcount = (int)r_long(p); | |
| 1371 | - if (PyErr_Occurred()) | ||
| 1376 | + if (argcount == -1 && PyErr_Occurred()) | ||
| 1372 | 1377 | goto code_error; | |
| 1373 | 1378 | posonlyargcount = (int)r_long(p); | |
| 1374 | - if (PyErr_Occurred()) { | ||
| 1379 | + if (posonlyargcount == -1 && PyErr_Occurred()) { | ||
| 1375 | 1380 | goto code_error; | |
| 1376 | 1381 | } | |
| 1377 | 1382 | kwonlyargcount = (int)r_long(p); | |
| 1378 | - if (PyErr_Occurred()) | ||
| 1383 | + if (kwonlyargcount == -1 && PyErr_Occurred()) | ||
| 1379 | 1384 | goto code_error; | |
| 1380 | 1385 | stacksize = (int)r_long(p); | |
| 1381 | - if (PyErr_Occurred()) | ||
| 1386 | + if (stacksize == -1 && PyErr_Occurred()) | ||
| 1382 | 1387 | goto code_error; | |
| 1383 | 1388 | flags = (int)r_long(p); | |
| 1384 | - if (PyErr_Occurred()) | ||
| 1389 | + if (flags == -1 && PyErr_Occurred()) | ||
| 1385 | 1390 | goto code_error; | |
| 1386 | 1391 | code = r_object(p); | |
| 1387 | 1392 | if (code == NULL) | |
@@ -1454,6 +1459,10 @@ r_object(RFILE *p) | |||
| 1454 | 1459 | v = r_ref_insert(v, idx, flag, p); | |
| 1455 | 1460 | ||
| 1456 | 1461 | code_error: | |
| 1462 | + if (v == NULL && !PyErr_Occurred()) { | ||
| 1463 | + PyErr_SetString(PyExc_TypeError, | ||
| 1464 | + "NULL object in marshal data for code object"); | ||
| 1465 | + } | ||
| 1457 | 1466 | Py_XDECREF(code); | |
| 1458 | 1467 | Py_XDECREF(consts); | |
| 1459 | 1468 | Py_XDECREF(names); | |
@@ -1471,9 +1480,10 @@ r_object(RFILE *p) | |||
| 1471 | 1480 | case TYPE_REF: | |
| 1472 | 1481 | n = r_long(p); | |
| 1473 | 1482 | if (n < 0 || n >= PyList_GET_SIZE(p->refs)) { | |
| 1474 | - if (n == -1 && PyErr_Occurred()) | ||
| 1475 | - break; | ||
| 1476 | - PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); | ||
| 1483 | + if (!PyErr_Occurred()) { | ||
| 1484 | + PyErr_SetString(PyExc_ValueError, | ||
| 1485 | + "bad marshal data (invalid reference)"); | ||
| 1486 | + } | ||
| 1477 | 1487 | break; | |
| 1478 | 1488 | } | |
| 1479 | 1489 | v = PyList_GET_ITEM(p->refs, n); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments