summaryrefslogtreecommitdiffstats
path: root/Python/marshal.c
diff options
context:
space:
mode:
authorMichael W. Hudson <mwh@python.net>2005-06-03 14:41:55 (GMT)
committerMichael W. Hudson <mwh@python.net>2005-06-03 14:41:55 (GMT)
commitdf88846ebca9186514e86bc2067242233ade4608 (patch)
tree345828bee8f325fc38b74827a08f80e098dff9ea /Python/marshal.c
parent268e61cf7458d85d2e100480635390ebd480088f (diff)
downloadcpython-df88846ebca9186514e86bc2067242233ade4608.zip
cpython-df88846ebca9186514e86bc2067242233ade4608.tar.gz
cpython-df88846ebca9186514e86bc2067242233ade4608.tar.bz2
This is my patch:
[ 1180995 ] binary formats for marshalling floats Adds 2 new type codes for marshal (binary floats and binary complexes), a new marshal version (2), updates MAGIC and fiddles the de-serializing of code objects to be less likely to clobber the real reason for failing if it fails.
Diffstat (limited to 'Python/marshal.c')
-rw-r--r--Python/marshal.c240
1 files changed, 175 insertions, 65 deletions
diff --git a/Python/marshal.c b/Python/marshal.c
index d0fcac7..2535cb5 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -15,28 +15,30 @@
*/
#define MAX_MARSHAL_STACK_DEPTH 5000
-#define TYPE_NULL '0'
-#define TYPE_NONE 'N'
-#define TYPE_FALSE 'F'
-#define TYPE_TRUE 'T'
-#define TYPE_STOPITER 'S'
-#define TYPE_ELLIPSIS '.'
-#define TYPE_INT 'i'
-#define TYPE_INT64 'I'
-#define TYPE_FLOAT 'f'
-#define TYPE_COMPLEX 'x'
-#define TYPE_LONG 'l'
-#define TYPE_STRING 's'
-#define TYPE_INTERNED 't'
-#define TYPE_STRINGREF 'R'
-#define TYPE_TUPLE '('
-#define TYPE_LIST '['
-#define TYPE_DICT '{'
-#define TYPE_CODE 'c'
-#define TYPE_UNICODE 'u'
-#define TYPE_UNKNOWN '?'
-#define TYPE_SET '<'
-#define TYPE_FROZENSET '>'
+#define TYPE_NULL '0'
+#define TYPE_NONE 'N'
+#define TYPE_FALSE 'F'
+#define TYPE_TRUE 'T'
+#define TYPE_STOPITER 'S'
+#define TYPE_ELLIPSIS '.'
+#define TYPE_INT 'i'
+#define TYPE_INT64 'I'
+#define TYPE_FLOAT 'f'
+#define TYPE_BINARY_FLOAT 'g'
+#define TYPE_COMPLEX 'x'
+#define TYPE_BINARY_COMPLEX 'y'
+#define TYPE_LONG 'l'
+#define TYPE_STRING 's'
+#define TYPE_INTERNED 't'
+#define TYPE_STRINGREF 'R'
+#define TYPE_TUPLE '('
+#define TYPE_LIST '['
+#define TYPE_DICT '{'
+#define TYPE_CODE 'c'
+#define TYPE_UNICODE 'u'
+#define TYPE_UNKNOWN '?'
+#define TYPE_SET '<'
+#define TYPE_FROZENSET '>'
typedef struct {
FILE *fp;
@@ -47,6 +49,7 @@ typedef struct {
char *ptr;
char *end;
PyObject *strings; /* dict on marshal, list on unmarshal */
+ int version;
} WFILE;
#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
@@ -165,32 +168,62 @@ w_object(PyObject *v, WFILE *p)
w_short(ob->ob_digit[i], p);
}
else if (PyFloat_Check(v)) {
- char buf[256]; /* Plenty to format any double */
- PyFloat_AsReprString(buf, (PyFloatObject *)v);
- n = strlen(buf);
- w_byte(TYPE_FLOAT, p);
- w_byte(n, p);
- w_string(buf, n, p);
+ if (p->version > 1) {
+ char buf[8];
+ if (_PyFloat_Pack8(PyFloat_AsDouble(v),
+ buf, 1) < 0) {
+ p->error = 1;
+ return;
+ }
+ w_byte(TYPE_BINARY_FLOAT, p);
+ w_string(buf, 8, p);
+ }
+ else {
+ char buf[256]; /* Plenty to format any double */
+ PyFloat_AsReprString(buf, (PyFloatObject *)v);
+ n = strlen(buf);
+ w_byte(TYPE_FLOAT, p);
+ w_byte(n, p);
+ w_string(buf, n, p);
+ }
}
#ifndef WITHOUT_COMPLEX
else if (PyComplex_Check(v)) {
- char buf[256]; /* Plenty to format any double */
- PyFloatObject *temp;
- w_byte(TYPE_COMPLEX, p);
- temp = (PyFloatObject*)PyFloat_FromDouble(
- PyComplex_RealAsDouble(v));
- PyFloat_AsReprString(buf, temp);
- Py_DECREF(temp);
- n = strlen(buf);
- w_byte(n, p);
- w_string(buf, n, p);
- temp = (PyFloatObject*)PyFloat_FromDouble(
- PyComplex_ImagAsDouble(v));
- PyFloat_AsReprString(buf, temp);
- Py_DECREF(temp);
- n = strlen(buf);
- w_byte(n, p);
- w_string(buf, n, p);
+ if (p->version > 1) {
+ char buf[8];
+ if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
+ buf, 1) < 0) {
+ p->error = 1;
+ return;
+ }
+ w_byte(TYPE_BINARY_COMPLEX, p);
+ w_string(buf, 8, p);
+ if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
+ buf, 1) < 0) {
+ p->error = 1;
+ return;
+ }
+ w_string(buf, 8, p);
+ }
+ else {
+ char buf[256]; /* Plenty to format any double */
+ PyFloatObject *temp;
+ w_byte(TYPE_COMPLEX, p);
+ temp = (PyFloatObject*)PyFloat_FromDouble(
+ PyComplex_RealAsDouble(v));
+ PyFloat_AsReprString(buf, temp);
+ Py_DECREF(temp);
+ n = strlen(buf);
+ w_byte(n, p);
+ w_string(buf, n, p);
+ temp = (PyFloatObject*)PyFloat_FromDouble(
+ PyComplex_ImagAsDouble(v));
+ PyFloat_AsReprString(buf, temp);
+ Py_DECREF(temp);
+ n = strlen(buf);
+ w_byte(n, p);
+ w_string(buf, n, p);
+ }
}
#endif
else if (PyString_Check(v)) {
@@ -335,6 +368,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
wf.error = 0;
wf.depth = 0;
wf.strings = NULL;
+ wf.version = version;
w_long(x, &wf);
}
@@ -346,6 +380,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
wf.error = 0;
wf.depth = 0;
wf.strings = (version > 0) ? PyDict_New() : NULL;
+ wf.version = version;
w_object(x, &wf);
Py_XDECREF(wf.strings);
}
@@ -519,6 +554,22 @@ r_object(RFILE *p)
return PyFloat_FromDouble(dx);
}
+ case TYPE_BINARY_FLOAT:
+ {
+ char buf[8];
+ double x;
+ if (r_string(buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ return NULL;
+ }
+ x = _PyFloat_Unpack8(buf, 1);
+ if (x == -1.0 && PyErr_Occurred()) {
+ return NULL;
+ }
+ return PyFloat_FromDouble(x);
+ }
+
#ifndef WITHOUT_COMPLEX
case TYPE_COMPLEX:
{
@@ -546,6 +597,31 @@ r_object(RFILE *p)
PyFPE_END_PROTECT(c)
return PyComplex_FromCComplex(c);
}
+
+ case TYPE_BINARY_COMPLEX:
+ {
+ char buf[8];
+ Py_complex c;
+ if (r_string(buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ return NULL;
+ }
+ c.real = _PyFloat_Unpack8(buf, 1);
+ if (c.real == -1.0 && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (r_string(buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ return NULL;
+ }
+ c.imag = _PyFloat_Unpack8(buf, 1);
+ if (c.imag == -1.0 && PyErr_Occurred()) {
+ return NULL;
+ }
+ return PyComplex_FromCComplex(c);
+ }
#endif
case TYPE_INTERNED:
@@ -707,30 +783,63 @@ r_object(RFILE *p)
return NULL;
}
else {
- int argcount = r_long(p);
- int nlocals = r_long(p);
- int stacksize = r_long(p);
- int flags = r_long(p);
- PyObject *code = r_object(p);
- PyObject *consts = r_object(p);
- PyObject *names = r_object(p);
- PyObject *varnames = r_object(p);
- PyObject *freevars = r_object(p);
- PyObject *cellvars = r_object(p);
- PyObject *filename = r_object(p);
- PyObject *name = r_object(p);
- int firstlineno = r_long(p);
- PyObject *lnotab = r_object(p);
-
- if (!PyErr_Occurred()) {
- v = (PyObject *) PyCode_New(
+ int argcount;
+ int nlocals;
+ int stacksize;
+ int flags;
+ PyObject *code = NULL;
+ PyObject *consts = NULL;
+ PyObject *names = NULL;
+ PyObject *varnames = NULL;
+ PyObject *freevars = NULL;
+ PyObject *cellvars = NULL;
+ PyObject *filename = NULL;
+ PyObject *name = NULL;
+ int firstlineno;
+ PyObject *lnotab = NULL;
+
+ v = NULL;
+
+ argcount = r_long(p);
+ nlocals = r_long(p);
+ stacksize = r_long(p);
+ flags = r_long(p);
+ code = r_object(p);
+ if (code == NULL)
+ goto code_error;
+ consts = r_object(p);
+ if (consts == NULL)
+ goto code_error;
+ names = r_object(p);
+ if (names == NULL)
+ goto code_error;
+ varnames = r_object(p);
+ if (varnames == NULL)
+ goto code_error;
+ freevars = r_object(p);
+ if (freevars == NULL)
+ goto code_error;
+ cellvars = r_object(p);
+ if (cellvars == NULL)
+ goto code_error;
+ filename = r_object(p);
+ if (filename == NULL)
+ goto code_error;
+ name = r_object(p);
+ if (name == NULL)
+ goto code_error;
+ firstlineno = r_long(p);
+ lnotab = r_object(p);
+ if (lnotab == NULL)
+ goto code_error;
+
+ v = (PyObject *) PyCode_New(
argcount, nlocals, stacksize, flags,
code, consts, names, varnames,
freevars, cellvars, filename, name,
firstlineno, lnotab);
- }
- else
- v = NULL;
+
+ code_error:
Py_XDECREF(code);
Py_XDECREF(consts);
Py_XDECREF(names);
@@ -882,6 +991,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
wf.end = wf.ptr + PyString_Size(wf.str);
wf.error = 0;
wf.depth = 0;
+ wf.version = version;
wf.strings = (version > 0) ? PyDict_New() : NULL;
w_object(x, &wf);
Py_XDECREF(wf.strings);