[Python-checkins] r71312 - python/branches/py3k-short-float-repr/Python/dtoa.c

mark.dickinson python-checkins at python.org
Mon Apr 6 18:34:41 CEST 2009


Author: mark.dickinson
Date: Mon Apr  6 18:34:40 2009
New Revision: 71312

Log:
Add failure checks throughout _Py_dg_dtoa


Modified:
   python/branches/py3k-short-float-repr/Python/dtoa.c

Modified: python/branches/py3k-short-float-repr/Python/dtoa.c
==============================================================================
--- python/branches/py3k-short-float-repr/Python/dtoa.c	(original)
+++ python/branches/py3k-short-float-repr/Python/dtoa.c	Mon Apr  6 18:34:40 2009
@@ -416,6 +416,7 @@
 Bfree
 	(Bigint *v)
 {
+	assert(v != NULL);
 	if (v) {
 		if (v->k > Kmax)
 			FREE((void*)v);
@@ -2074,8 +2075,9 @@
  *	   calculation.
  */
 
-/* Note: to avoid memory leakage, a successful call to _Py_dg_dtoa should
-   always be matched by a call to _Py_dg_freedtoa. */
+/* Additional notes (METD): (1) returns NULL on failure.  (2) to avoid memory
+   leakage, a successful call to _Py_dg_dtoa should always be matched by a
+   call to _Py_dg_freedtoa. */
 
  char *
 _Py_dg_dtoa
@@ -2126,6 +2128,11 @@
 	double ds;
 	char *s, *s0;
 
+	/* set pointers to NULL, to silence gcc compiler warnings and make
+	   cleanup easier on error */
+	mlo = mhi = b = S = 0;
+	s0 = 0;
+
 	u.d = dd;
 	if (word0(&u) & Sign_bit) {
 		/* set sign for everything, including 0's and NaNs */
@@ -2150,6 +2157,8 @@
 
 
 	b = d2b(&u, &be, &bbits);
+	if (b == NULL)
+		goto failed_malloc;
 	if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
 		dval(&d2) = dval(&u);
 		word0(&d2) &= Frac_mask1;
@@ -2260,7 +2269,10 @@
 			if (i <= 0)
 				i = 1;
 		}
-	s = s0 = rv_alloc(i);
+	s0 = rv_alloc(i);
+	if (s0 == NULL)
+		goto failed_malloc;
+	s = s0;
 
 
 	if (ilim >= 0 && ilim <= Quick_max && try_quick) {
@@ -2406,7 +2418,6 @@
 
 	m2 = b2;
 	m5 = b5;
-	mhi = mlo = 0;
 	if (leftright) {
 		i =
 			denorm ? be + (Bias + (P-1) - 1 + 1) :
@@ -2414,6 +2425,8 @@
 		b2 += i;
 		s2 += i;
 		mhi = i2b(1);
+		if (mhi == NULL)
+			goto failed_malloc;
 		}
 	if (m2 > 0 && s2 > 0) {
 		i = m2 < s2 ? m2 : s2;
@@ -2425,19 +2438,34 @@
 		if (leftright) {
 			if (m5 > 0) {
 				mhi = pow5mult(mhi, m5);
+				if (mhi == NULL)
+					goto failed_malloc;
 				b1 = mult(mhi, b);
 				Bfree(b);
 				b = b1;
+				if (b == NULL)
+					goto failed_malloc;
 				}
-			if ((j = b5 - m5))
+			if ((j = b5 - m5)) {
 				b = pow5mult(b, j);
+				if (b == NULL)
+					goto failed_malloc;
+				}
 			}
-		else
+		else {
 			b = pow5mult(b, b5);
+			if (b == NULL)
+				goto failed_malloc;
+			}
 		}
 	S = i2b(1);
-	if (s5 > 0)
+	if (S == NULL)
+		goto failed_malloc;
+	if (s5 > 0) {
 		S = pow5mult(S, s5);
+		if (S == NULL)
+			goto failed_malloc;
+		}
 
 	/* Check for special case that d is a normalized power of 2. */
 
@@ -2468,34 +2496,55 @@
 	b2 += i;
 	m2 += i;
 	s2 += i;
-	if (b2 > 0)
+	if (b2 > 0) {
 		b = lshift(b, b2);
-	if (s2 > 0)
+		if (b == NULL)
+			goto failed_malloc;
+		}
+	if (s2 > 0) {
 		S = lshift(S, s2);
+		if (S == NULL)
+			goto failed_malloc;
+		}
 	if (k_check) {
 		if (cmp(b,S) < 0) {
 			k--;
 			b = multadd(b, 10, 0);	/* we botched the k estimate */
-			if (leftright)
+			if (b == NULL)
+				goto failed_malloc;
+			if (leftright) {
 				mhi = multadd(mhi, 10, 0);
+				if (mhi == NULL)
+					goto failed_malloc;
+				}
 			ilim = ilim1;
 			}
 		}
 	if (ilim <= 0 && (mode == 3 || mode == 5)) {
-		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+		if (ilim < 0) {
 			/* no digits, fcvt style */
  no_digits:
 			k = -1 - ndigits;
 			goto ret;
 			}
+		else {
+			S = multadd(S, 5, 0);
+			if (S == NULL)
+				goto failed_malloc;
+			if (cmp(b, S) <= 0)
+				goto no_digits;
+			}
  one_digit:
 		*s++ = '1';
 		k++;
 		goto ret;
 		}
 	if (leftright) {
-		if (m2 > 0)
+		if (m2 > 0) {
 			mhi = lshift(mhi, m2);
+			if (mhi == NULL)
+				goto failed_malloc;
+			}
 
 		/* Compute mlo -- check for special case
 		 * that d is a normalized power of 2.
@@ -2504,8 +2553,12 @@
 		mlo = mhi;
 		if (spec_case) {
 			mhi = Balloc(mhi->k);
+			if (mhi == NULL)
+				goto failed_malloc;
 			Bcopy(mhi, mlo);
 			mhi = lshift(mhi, Log2P);
+			if (mhi == NULL)
+				goto failed_malloc;
 			}
 
 		for(i = 1;;i++) {
@@ -2515,6 +2568,8 @@
 			 */
 			j = cmp(b, mlo);
 			delta = diff(S, mhi);
+			if (delta == NULL)
+				goto failed_malloc;
 			j1 = delta->sign ? 1 : cmp(b, delta);
 			Bfree(delta);
 			if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
@@ -2534,6 +2589,8 @@
 					}
 				if (j1 > 0) {
 					b = lshift(b, 1);
+					if (b == NULL)
+						goto failed_malloc;
 					j1 = cmp(b, S);
 					if ((j1 > 0 || (j1 == 0 && dig & 1))
 					&& dig++ == '9')
@@ -2556,11 +2613,20 @@
 			if (i == ilim)
 				break;
 			b = multadd(b, 10, 0);
-			if (mlo == mhi)
+			if (b == NULL)
+				goto failed_malloc;
+			if (mlo == mhi) {
 				mlo = mhi = multadd(mhi, 10, 0);
+				if (mlo == NULL)
+					goto failed_malloc;
+				}
 			else {
 				mlo = multadd(mlo, 10, 0);
+				if (mlo == NULL)
+					goto failed_malloc;
 				mhi = multadd(mhi, 10, 0);
+				if (mhi == NULL)
+					goto failed_malloc;
 				}
 			}
 		}
@@ -2573,11 +2639,15 @@
 			if (i >= ilim)
 				break;
 			b = multadd(b, 10, 0);
+			if (b == NULL)
+				goto failed_malloc;
 			}
 
 	/* Round off last digit */
 
 	b = lshift(b, 1);
+	if (b == NULL)
+		goto failed_malloc;
 	j = cmp(b, S);
 	if (j > 0 || (j == 0 && dig & 1)) {
  roundoff:
@@ -2607,6 +2677,18 @@
 	if (rve)
 		*rve = s;
 	return s0;
+ failed_malloc:
+	if (S)
+		Bfree(S);
+	if (mlo && mlo != mhi)
+		Bfree(mlo);
+	if (mhi)
+		Bfree(mhi);
+	if (b)
+		Bfree(b);
+	if (s0)
+		_Py_dg_freedtoa(s0);
+	return NULL;
 	}
 #ifdef __cplusplus
 }


More information about the Python-checkins mailing list