[Python-checkins] python/dist/src/Modules cPickle.c,2.73.2.1.2.3,2.73.2.1.2.4 structmodule.c,2.51.8.1,2.51.8.2

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
2003年3月20日 10:31:30 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv6172/Modules
Modified Files:
 Tag: release22-maint
	cPickle.c structmodule.c 
Log Message:
SF bug 705836: struct.pack of floats in non-native endian order
pack_float, pack_double, save_float: All the routines for creating
IEEE-format packed representations of floats and doubles simply ignored
that rounding can (in rare cases) propagate out of a long string of
1 bits. At worst, the end-off carry can (by mistake) interfere with
the exponent value, and then unpacking yields a result wrong by a factor
of 2. In less severe cases, it can end up losing more low-order bits
than intended, or fail to catch overflow *caused* by rounding.
Index: cPickle.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/cPickle.c,v
retrieving revision 2.73.2.1.2.3
retrieving revision 2.73.2.1.2.4
diff -C2 -d -r2.73.2.1.2.3 -r2.73.2.1.2.4
*** cPickle.c	24 Sep 2002 11:53:34 -0000	2.73.2.1.2.3
--- cPickle.c	20 Mar 2003 18:31:13 -0000	2.73.2.1.2.4
***************
*** 706,710 ****
 static int
 put(Picklerobject *self, PyObject *ob) {
! if (ob->ob_refcnt < 2 || self->fast) 
 return 0;
 
--- 706,710 ----
 static int
 put(Picklerobject *self, PyObject *ob) {
! if (ob->ob_refcnt < 2 || self->fast)
 return 0;
 
***************
*** 922,926 ****
 }
 
! int 
 fast_save_leave(Picklerobject *self, PyObject *obj)
 {
--- 922,926 ----
 }
 
! int
 fast_save_leave(Picklerobject *self, PyObject *obj)
 {
***************
*** 1065,1074 ****
 }
 
! if (e >= 1024) {
! /* XXX 1024 itself is reserved for Inf/NaN */
! PyErr_SetString(PyExc_OverflowError,
! "float too large to pack with d format");
! return -1;
! }
 else if (e < -1022) {
 /* Gradual underflow */
--- 1065,1070 ----
 }
 
! if (e >= 1024)
! 	 goto Overflow;
 else if (e < -1022) {
 /* Gradual underflow */
***************
*** 1084,1090 ****
--- 1080,1103 ----
 f *= 268435456.0; /* 2**28 */
 fhi = (long) floor(f); /* Truncate */
+ 	assert(fhi < 268435456);
+ 
 f -= (double)fhi;
 f *= 16777216.0; /* 2**24 */
 flo = (long) floor(f + 0.5); /* Round */
+ 	assert(flo <= 16777216);
+ 	if (flo >> 24) {
+ 		/* The carry propagated out of a string of 24 1 bits. */
+ 		flo = 0;
+ 		++fhi;
+ 		if (fhi >> 28) {
+ 			/* And it also progagated out of the next
+ 			 * 28 bits.
+ 			 */
+ 			fhi = 0;
+ 			++e;
+ 			if (e >= 2047)
+ 				goto Overflow;
+ 		}
+ 	}
 
 /* First byte */
***************
*** 1132,1135 ****
--- 1145,1153 ----
 
 return 0;
+ 
+ Overflow:
+ 	PyErr_SetString(PyExc_OverflowError,
+ 			"float too large to pack with d format");
+ 	return -1;
 }
 
***************
*** 2104,2110 ****
 static PyObject *
 Pickle_clear_memo(Picklerobject *self, PyObject *args) {
! if (!PyArg_ParseTuple(args,":clear_memo")) 
 	return NULL;
! if (self->memo) 
 	PyDict_Clear(self->memo);
 Py_INCREF(Py_None);
--- 2122,2128 ----
 static PyObject *
 Pickle_clear_memo(Picklerobject *self, PyObject *args) {
! if (!PyArg_ParseTuple(args,":clear_memo"))
 	return NULL;
! if (self->memo)
 	PyDict_Clear(self->memo);
 Py_INCREF(Py_None);
***************
*** 2121,2125 ****
 
 /* Can be called by Python code or C code */
! if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear)) 
 return NULL;
 
--- 2139,2143 ----
 
 /* Can be called by Python code or C code */
! if (args && !PyArg_ParseTuple(args, "|i:getvalue", &clear))
 return NULL;
 
***************
*** 2483,2487 ****
 
 static PyGetSetDef Pickler_getsets[] = {
! {"persistent_id", (getter)Pickler_get_pers_func, 
 (setter)Pickler_set_pers_func},
 {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func},
--- 2501,2505 ----
 
 static PyGetSetDef Pickler_getsets[] = {
! {"persistent_id", (getter)Pickler_get_pers_func,
 (setter)Pickler_set_pers_func},
 {"inst_persistent_id", NULL, (setter)Pickler_set_inst_pers_func},
Index: structmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v
retrieving revision 2.51.8.1
retrieving revision 2.51.8.2
diff -C2 -d -r2.51.8.1 -r2.51.8.2
*** structmodule.c	23 Sep 2002 20:54:04 -0000	2.51.8.1
--- structmodule.c	20 Mar 2003 18:31:20 -0000	2.51.8.2
***************
*** 226,235 ****
 	}
 
! 	if (e >= 128) {
! 		/* XXX 128 itself is reserved for Inf/NaN */
! 		PyErr_SetString(PyExc_OverflowError,
! 				"float too large to pack with f format");
! 		return -1;
! 	}
 	else if (e < -126) {
 		/* Gradual underflow */
--- 226,231 ----
 	}
 
! 	if (e >= 128)
! 		goto Overflow;
 	else if (e < -126) {
 		/* Gradual underflow */
***************
*** 244,247 ****
--- 240,251 ----
 	f *= 8388608.0; /* 2**23 */
 	fbits = (long) floor(f + 0.5); /* Round */
+ 	assert(fbits <= 8388608);
+ 	if (fbits >> 23) {
+ 		/* The carry propagated out of a string of 23 1 bits. */
+ 		fbits = 0;
+ 		++e;
+ 		if (e >= 255)
+ 			goto Overflow;
+ 	}
 
 	/* First byte */
***************
*** 262,265 ****
--- 266,274 ----
 	/* Done */
 	return 0;
+ 
+ Overflow:
+ 	PyErr_SetString(PyExc_OverflowError,
+ 			"float too large to pack with f format");
+ 	return -1;
 }
 
***************
*** 297,306 ****
 	}
 
! 	if (e >= 1024) {
! 		/* XXX 1024 itself is reserved for Inf/NaN */
! 		PyErr_SetString(PyExc_OverflowError,
! 				"float too large to pack with d format");
! 		return -1;
! 	}
 	else if (e < -1022) {
 		/* Gradual underflow */
--- 306,311 ----
 	}
 
! 	if (e >= 1024)
! 		goto Overflow;
 	else if (e < -1022) {
 		/* Gradual underflow */
***************
*** 316,322 ****
--- 321,342 ----
 	f *= 268435456.0; /* 2**28 */
 	fhi = (long) floor(f); /* Truncate */
+ 	assert(fhi < 268435456);
+ 
 	f -= (double)fhi;
 	f *= 16777216.0; /* 2**24 */
 	flo = (long) floor(f + 0.5); /* Round */
+ 	assert(flo <= 16777216);
+ 	if (flo >> 24) {
+ 		/* The carry propagated out of a string of 24 1 bits. */
+ 		flo = 0;
+ 		++fhi;
+ 		if (fhi >> 28) {
+ 			/* And it also progagated out of the next 28 bits. */
+ 			fhi = 0;
+ 			++e;
+ 			if (e >= 2047)
+ 				goto Overflow;
+ 		}
+ 	}
 
 	/* First byte */
***************
*** 354,357 ****
--- 374,382 ----
 	/* Done */
 	return 0;
+ 
+ Overflow:
+ 	PyErr_SetString(PyExc_OverflowError,
+ 			"float too large to pack with d format");
+ 	return -1;
 }
 

AltStyle によって変換されたページ (->オリジナル) /