1515 */
1616#define MAX_MARSHAL_STACK_DEPTH 5000
1717
18- #define TYPE_NULL '0'
19- #define TYPE_NONE 'N'
20- #define TYPE_FALSE 'F'
21- #define TYPE_TRUE 'T'
22- #define TYPE_STOPITER 'S'
23- #define TYPE_ELLIPSIS '.'
24- #define TYPE_INT 'i'
25- #define TYPE_INT64 'I'
26- #define TYPE_FLOAT 'f'
27- #define TYPE_COMPLEX 'x'
28- #define TYPE_LONG 'l'
29- #define TYPE_STRING 's'
30- #define TYPE_INTERNED 't'
31- #define TYPE_STRINGREF 'R'
32- #define TYPE_TUPLE '('
33- #define TYPE_LIST '['
34- #define TYPE_DICT '{'
35- #define TYPE_CODE 'c'
36- #define TYPE_UNICODE 'u'
37- #define TYPE_UNKNOWN '?'
38- #define TYPE_SET '<'
39- #define TYPE_FROZENSET '>'
18+ #define TYPE_NULL '0'
19+ #define TYPE_NONE 'N'
20+ #define TYPE_FALSE 'F'
21+ #define TYPE_TRUE 'T'
22+ #define TYPE_STOPITER 'S'
23+ #define TYPE_ELLIPSIS '.'
24+ #define TYPE_INT 'i'
25+ #define TYPE_INT64 'I'
26+ #define TYPE_FLOAT 'f'
27+ #define TYPE_BINARY_FLOAT 'g'
28+ #define TYPE_COMPLEX 'x'
29+ #define TYPE_BINARY_COMPLEX 'y'
30+ #define TYPE_LONG 'l'
31+ #define TYPE_STRING 's'
32+ #define TYPE_INTERNED 't'
33+ #define TYPE_STRINGREF 'R'
34+ #define TYPE_TUPLE '('
35+ #define TYPE_LIST '['
36+ #define TYPE_DICT '{'
37+ #define TYPE_CODE 'c'
38+ #define TYPE_UNICODE 'u'
39+ #define TYPE_UNKNOWN '?'
40+ #define TYPE_SET '<'
41+ #define TYPE_FROZENSET '>'
4042
4143typedef struct {
4244 FILE * fp ;
@@ -47,6 +49,7 @@ typedef struct {
4749 char * ptr ;
4850 char * end ;
4951 PyObject * strings ; /* dict on marshal, list on unmarshal */
52+ int version ;
5053} WFILE ;
5154
5255#define w_byte (c , p ) if (((p)->fp)) putc((c), (p)->fp); \
@@ -165,32 +168,62 @@ w_object(PyObject *v, WFILE *p)
165168 w_short (ob -> ob_digit [i ], p );
166169 }
167170 else if (PyFloat_Check (v )) {
168- char buf [256 ]; /* Plenty to format any double */
169- PyFloat_AsReprString (buf , (PyFloatObject * )v );
170- n = strlen (buf );
171- w_byte (TYPE_FLOAT , p );
172- w_byte (n , p );
173- w_string (buf , n , p );
171+ if (p -> version > 1 ) {
172+ char buf [8 ];
173+ if (_PyFloat_Pack8 (PyFloat_AsDouble (v ),
174+ buf , 1 ) < 0 ) {
175+ p -> error = 1 ;
176+ return ;
177+ }
178+ w_byte (TYPE_BINARY_FLOAT , p );
179+ w_string (buf , 8 , p );
180+ }
181+ else {
182+ char buf [256 ]; /* Plenty to format any double */
183+ PyFloat_AsReprString (buf , (PyFloatObject * )v );
184+ n = strlen (buf );
185+ w_byte (TYPE_FLOAT , p );
186+ w_byte (n , p );
187+ w_string (buf , n , p );
188+ }
174189 }
175190#ifndef WITHOUT_COMPLEX
176191 else if (PyComplex_Check (v )) {
177- char buf [256 ]; /* Plenty to format any double */
178- PyFloatObject * temp ;
179- w_byte (TYPE_COMPLEX , p );
180- temp = (PyFloatObject * )PyFloat_FromDouble (
181- PyComplex_RealAsDouble (v ));
182- PyFloat_AsReprString (buf , temp );
183- Py_DECREF (temp );
184- n = strlen (buf );
185- w_byte (n , p );
186- w_string (buf , n , p );
187- temp = (PyFloatObject * )PyFloat_FromDouble (
188- PyComplex_ImagAsDouble (v ));
189- PyFloat_AsReprString (buf , temp );
190- Py_DECREF (temp );
191- n = strlen (buf );
192- w_byte (n , p );
193- w_string (buf , n , p );
192+ if (p -> version > 1 ) {
193+ char buf [8 ];
194+ if (_PyFloat_Pack8 (PyComplex_RealAsDouble (v ),
195+ buf , 1 ) < 0 ) {
196+ p -> error = 1 ;
197+ return ;
198+ }
199+ w_byte (TYPE_BINARY_COMPLEX , p );
200+ w_string (buf , 8 , p );
201+ if (_PyFloat_Pack8 (PyComplex_ImagAsDouble (v ),
202+ buf , 1 ) < 0 ) {
203+ p -> error = 1 ;
204+ return ;
205+ }
206+ w_string (buf , 8 , p );
207+ }
208+ else {
209+ char buf [256 ]; /* Plenty to format any double */
210+ PyFloatObject * temp ;
211+ w_byte (TYPE_COMPLEX , p );
212+ temp = (PyFloatObject * )PyFloat_FromDouble (
213+ PyComplex_RealAsDouble (v ));
214+ PyFloat_AsReprString (buf , temp );
215+ Py_DECREF (temp );
216+ n = strlen (buf );
217+ w_byte (n , p );
218+ w_string (buf , n , p );
219+ temp = (PyFloatObject * )PyFloat_FromDouble (
220+ PyComplex_ImagAsDouble (v ));
221+ PyFloat_AsReprString (buf , temp );
222+ Py_DECREF (temp );
223+ n = strlen (buf );
224+ w_byte (n , p );
225+ w_string (buf , n , p );
226+ }
194227 }
195228#endif
196229 else if (PyString_Check (v )) {
@@ -335,6 +368,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
335368 wf .error = 0 ;
336369 wf .depth = 0 ;
337370 wf .strings = NULL ;
371+ wf .version = version ;
338372 w_long (x , & wf );
339373}
340374
@@ -346,6 +380,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
346380 wf .error = 0 ;
347381 wf .depth = 0 ;
348382 wf .strings = (version > 0 ) ? PyDict_New () : NULL ;
383+ wf .version = version ;
349384 w_object (x , & wf );
350385 Py_XDECREF (wf .strings );
351386}
@@ -519,6 +554,22 @@ r_object(RFILE *p)
519554 return PyFloat_FromDouble (dx );
520555 }
521556
557+ case TYPE_BINARY_FLOAT :
558+ {
559+ char buf [8 ];
560+ double x ;
561+ if (r_string (buf , 8 , p ) != 8 ) {
562+ PyErr_SetString (PyExc_EOFError ,
563+ "EOF read where object expected" );
564+ return NULL ;
565+ }
566+ x = _PyFloat_Unpack8 (buf , 1 );
567+ if (x == -1.0 && PyErr_Occurred ()) {
568+ return NULL ;
569+ }
570+ return PyFloat_FromDouble (x );
571+ }
572+
522573#ifndef WITHOUT_COMPLEX
523574 case TYPE_COMPLEX :
524575 {
@@ -546,6 +597,31 @@ r_object(RFILE *p)
546597 PyFPE_END_PROTECT (c )
547598 return PyComplex_FromCComplex (c );
548599 }
600+
601+ case TYPE_BINARY_COMPLEX :
602+ {
603+ char buf [8 ];
604+ Py_complex c ;
605+ if (r_string (buf , 8 , p ) != 8 ) {
606+ PyErr_SetString (PyExc_EOFError ,
607+ "EOF read where object expected" );
608+ return NULL ;
609+ }
610+ c .real = _PyFloat_Unpack8 (buf , 1 );
611+ if (c .real == -1.0 && PyErr_Occurred ()) {
612+ return NULL ;
613+ }
614+ if (r_string (buf , 8 , p ) != 8 ) {
615+ PyErr_SetString (PyExc_EOFError ,
616+ "EOF read where object expected" );
617+ return NULL ;
618+ }
619+ c .imag = _PyFloat_Unpack8 (buf , 1 );
620+ if (c .imag == -1.0 && PyErr_Occurred ()) {
621+ return NULL ;
622+ }
623+ return PyComplex_FromCComplex (c );
624+ }
549625#endif
550626
551627 case TYPE_INTERNED :
@@ -707,30 +783,63 @@ r_object(RFILE *p)
707783 return NULL ;
708784 }
709785 else {
710- int argcount = r_long (p );
711- int nlocals = r_long (p );
712- int stacksize = r_long (p );
713- int flags = r_long (p );
714- PyObject * code = r_object (p );
715- PyObject * consts = r_object (p );
716- PyObject * names = r_object (p );
717- PyObject * varnames = r_object (p );
718- PyObject * freevars = r_object (p );
719- PyObject * cellvars = r_object (p );
720- PyObject * filename = r_object (p );
721- PyObject * name = r_object (p );
722- int firstlineno = r_long (p );
723- PyObject * lnotab = r_object (p );
724-
725- if (!PyErr_Occurred ()) {
726- v = (PyObject * ) PyCode_New (
786+ int argcount ;
787+ int nlocals ;
788+ int stacksize ;
789+ int flags ;
790+ PyObject * code = NULL ;
791+ PyObject * consts = NULL ;
792+ PyObject * names = NULL ;
793+ PyObject * varnames = NULL ;
794+ PyObject * freevars = NULL ;
795+ PyObject * cellvars = NULL ;
796+ PyObject * filename = NULL ;
797+ PyObject * name = NULL ;
798+ int firstlineno ;
799+ PyObject * lnotab = NULL ;
800+
801+ v = NULL ;
802+
803+ argcount = r_long (p );
804+ nlocals = r_long (p );
805+ stacksize = r_long (p );
806+ flags = r_long (p );
807+ code = r_object (p );
808+ if (code == NULL )
809+ goto code_error ;
810+ consts = r_object (p );
811+ if (consts == NULL )
812+ goto code_error ;
813+ names = r_object (p );
814+ if (names == NULL )
815+ goto code_error ;
816+ varnames = r_object (p );
817+ if (varnames == NULL )
818+ goto code_error ;
819+ freevars = r_object (p );
820+ if (freevars == NULL )
821+ goto code_error ;
822+ cellvars = r_object (p );
823+ if (cellvars == NULL )
824+ goto code_error ;
825+ filename = r_object (p );
826+ if (filename == NULL )
827+ goto code_error ;
828+ name = r_object (p );
829+ if (name == NULL )
830+ goto code_error ;
831+ firstlineno = r_long (p );
832+ lnotab = r_object (p );
833+ if (lnotab == NULL )
834+ goto code_error ;
835+
836+ v = (PyObject * ) PyCode_New (
727837 argcount , nlocals , stacksize , flags ,
728838 code , consts , names , varnames ,
729839 freevars , cellvars , filename , name ,
730840 firstlineno , lnotab );
731- }
732- else
733- v = NULL ;
841+
842+ code_error :
734843 Py_XDECREF (code );
735844 Py_XDECREF (consts );
736845 Py_XDECREF (names );
@@ -882,6 +991,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
882991 wf .end = wf .ptr + PyString_Size (wf .str );
883992 wf .error = 0 ;
884993 wf .depth = 0 ;
994+ wf .version = version ;
885995 wf .strings = (version > 0 ) ? PyDict_New () : NULL ;
886996 w_object (x , & wf );
887997 Py_XDECREF (wf .strings );
0 commit comments