From 545686b279ef382ec35aa12afa1f9271ce6d5109 Mon Sep 17 00:00:00 2001
From: Neal Norwitz <nnorwitz@gmail.com>
Date: Thu, 28 Dec 2006 04:45:06 +0000
Subject: Remove PyFloat_AsReprString() and PyFloat_AsString() which should not
 have been public due to passing buffers without lengths.

---
 Include/floatobject.h | 19 +++++--------------
 Objects/floatobject.c | 43 ++++++++++++++++---------------------------
 Python/marshal.c      | 26 ++++++--------------------
 3 files changed, 27 insertions(+), 61 deletions(-)

diff --git a/Include/floatobject.h b/Include/floatobject.h
index f695de8..c3c18af 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -34,19 +34,6 @@ PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double);
 PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *);
 #define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
 
-/* Write repr(v) into the char buffer argument, followed by null byte.  The
-   buffer must be "big enough"; >= 100 is very safe.
-   PyFloat_AsReprString(buf, x) strives to print enough digits so that
-   PyFloat_FromString(buf) then reproduces x exactly. */
-PyAPI_FUNC(void) PyFloat_AsReprString(char*, PyFloatObject *v);
-
-/* Write str(v) into the char buffer argument, followed by null byte.  The
-   buffer must be "big enough"; >= 100 is very safe.  Note that it's
-   unusual to be able to get back the float you started with from
-   PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to
-   preserve precision across conversions. */
-PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v);
-
 /* _PyFloat_{Pack,Unpack}{4,8}
  *
  * The struct and pickle (at least) modules need an efficient platform-
@@ -82,6 +69,11 @@ PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v);
 PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le);
 PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
 
+/* Needed for the old way for marshal to store a floating point number.
+   Returns the string length copied into p, -1 on error.
+ */
+PyAPI_FUNC(int) _PyFloat_Repr(double x, char *p, size_t len);
+
 /* The unpack routines read 4 or 8 bytes, starting at p.  le is a bool
  * argument, true if the string is in little-endian format (exponent
  * last, at p+3 or p+7), false if big-endian (exponent first, at p).
@@ -93,7 +85,6 @@ PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
 PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le);
 PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le);
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index aab7612..9c6dadf 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -220,19 +220,18 @@ PyFloat_AsDouble(PyObject *op)
 /* Methods */
 
 static void
-format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
+format_double(char *buf, size_t buflen, double ob_fval, int precision)
 {
 	register char *cp;
 	char format[32];
-	/* Subroutine for float_repr and float_print.
+	/* Subroutine for float_repr, float_str, float_print and others.
 	   We want float numbers to be recognizable as such,
 	   i.e., they should contain a decimal point or an exponent.
 	   However, %g may print the number as an integer;
 	   in such cases, we append ".0" to the string. */
 
-	assert(PyFloat_Check(v));
 	PyOS_snprintf(format, 32, "%%.%ig", precision);
-	PyOS_ascii_formatd(buf, buflen, format, v->ob_fval);
+	PyOS_ascii_formatd(buf, buflen, format, ob_fval);
 	cp = buf;
 	if (*cp == '-')
 		cp++;
@@ -249,14 +248,11 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
 	}
 }
 
-/* XXX PyFloat_AsStringEx should not be a public API function (for one
-   XXX thing, its signature passes a buffer without a length; for another,
-   XXX it isn't useful outside this file).
-*/
-void
-PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
+static void
+format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
 {
-	format_float(buf, 100, v, precision);
+	assert(PyFloat_Check(v));
+	format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision);
 }
 
 /* Macro and helper that convert PyObject obj to a C double and store
@@ -312,21 +308,6 @@ convert_to_double(PyObject **v, double *dbl)
 #define PREC_REPR	17
 #define PREC_STR	12
 
-/* XXX PyFloat_AsString and PyFloat_AsReprString should be deprecated:
-   XXX they pass a char buffer without passing a length.
-*/
-void
-PyFloat_AsString(char *buf, PyFloatObject *v)
-{
-	format_float(buf, 100, v, PREC_STR);
-}
-
-void
-PyFloat_AsReprString(char *buf, PyFloatObject *v)
-{
-	format_float(buf, 100, v, PREC_REPR);
-}
-
 /* ARGSUSED */
 static int
 float_print(PyFloatObject *v, FILE *fp, int flags)
@@ -1275,7 +1256,7 @@ PyFloat_Fini(void)
 				if (PyFloat_CheckExact(p) &&
 				    p->ob_refcnt != 0) {
 					char buf[100];
-					PyFloat_AsString(buf, p);
+					format_float(buf, sizeof(buf), p, PREC_STR);
 					/* XXX(twouters) cast refcount to
 					   long until %zd is universally
 					   available
@@ -1527,6 +1508,14 @@ _PyFloat_Pack8(double x, unsigned char *p, int le)
 	}
 }
 
+/* Should only be used by marshal. */
+int
+_PyFloat_Repr(double x, char *p, size_t len)
+{
+	format_double(p, len, x, PREC_REPR);
+	return (int)strlen(p);
+}
+
 double
 _PyFloat_Unpack4(const unsigned char *p, int le)
 {
diff --git a/Python/marshal.c b/Python/marshal.c
index 4e02ac6..1819eac 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -182,8 +182,8 @@ w_object(PyObject *v, WFILE *p)
 		}
 		else {
 			char buf[256]; /* Plenty to format any double */
-			PyFloat_AsReprString(buf, (PyFloatObject *)v);
-			n = strlen(buf);
+			n = _PyFloat_Repr(PyFloat_AS_DOUBLE(v),
+					  buf, sizeof(buf));
 			w_byte(TYPE_FLOAT, p);
 			w_byte((int)n, p);
 			w_string(buf, (int)n, p);
@@ -209,28 +209,14 @@ w_object(PyObject *v, WFILE *p)
 		}
 		else {
 			char buf[256]; /* Plenty to format any double */
-			PyFloatObject *temp;
 			w_byte(TYPE_COMPLEX, p);
-			temp = (PyFloatObject*)PyFloat_FromDouble(
-				PyComplex_RealAsDouble(v));
-			if (!temp) {
-				p->error = 1;
-				return;
-			}
-			PyFloat_AsReprString(buf, temp);
-			Py_DECREF(temp);
+			n = _PyFloat_Repr(PyComplex_RealAsDouble(v),
+					  buf, sizeof(buf));
 			n = strlen(buf);
 			w_byte((int)n, p);
 			w_string(buf, (int)n, p);
-			temp = (PyFloatObject*)PyFloat_FromDouble(
-				PyComplex_ImagAsDouble(v));
-			if (!temp) {
-				p->error = 1;
-				return;
-			}
-			PyFloat_AsReprString(buf, temp);
-			Py_DECREF(temp);
-			n = strlen(buf);
+			n = _PyFloat_Repr(PyComplex_ImagAsDouble(v),
+					  buf, sizeof(buf));
 			w_byte((int)n, p);
 			w_string(buf, (int)n, p);
 		}
-- 
cgit v0.12

