[Python-checkins] python/dist/src/Objects fileobject.c,2.110.2.1,2.110.2.2 stringobject.c,2.102.2.4,2.102.2.5 unicodeobject.c,2.82.2.1,2.82.2.2

anthonybaxter@sourceforge.net anthonybaxter@sourceforge.net
Mon, 29 Apr 2002 20:58:49 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv9184/Objects

Modified Files:
      Tag: release21-maint
	fileobject.c stringobject.c unicodeobject.c 
Log Message:
backport tim_one's patch:

[Re-did unicodeobject.c - it's changed a lot since 2.1 :) Pretty confident
that it's correct]

Repair widespread misuse of _PyString_Resize.  Since it's clear people
don't understand how this function works, also beefed up the docs.  The
most common usage error is of this form (often spread out across gotos):

	if (_PyString_Resize(&s, n) < 0) {
		Py_DECREF(s);
		s = NULL;
		goto outtahere;
	}

The error is that if _PyString_Resize runs out of memory, it automatically
decrefs the input string object s (which also deallocates it, since its
refcount must be 1 upon entry), and sets s to NULL.  So if the "if"
branch ever triggers, it's an error to call Py_DECREF(s):  s is already
NULL!  A correct way to write the above is the simpler (and intended)

	if (_PyString_Resize(&s, n) < 0)
		goto outtahere;

Bugfix candidate.

Original patch(es):
python/dist/src/Objects/fileobject.c:2.161
python/dist/src/Objects/stringobject.c:2.161
python/dist/src/Objects/unicodeobject.c:2.147



Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.110.2.1
retrieving revision 2.110.2.2
diff -C2 -d -r2.110.2.1 -r2.110.2.2
*** fileobject.c	7 Jan 2002 06:42:37 -0000	2.110.2.1
--- fileobject.c	30 Apr 2002 03:58:47 -0000	2.110.2.2
***************
*** 1105,1111 ****
  	}
    cleanup:
! 	if (big_buffer) {
! 		Py_DECREF(big_buffer);
! 	}
  	return list;
  }
--- 1105,1109 ----
  	}
    cleanup:
! 	Py_XDECREF(big_buffer);
  	return list;
  }

Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.102.2.4
retrieving revision 2.102.2.5
diff -C2 -d -r2.102.2.4 -r2.102.2.5
*** stringobject.c	23 May 2001 14:38:53 -0000	2.102.2.4
--- stringobject.c	30 Apr 2002 03:58:47 -0000	2.102.2.5
***************
*** 1450,1455 ****
  	}
  	/* Fix the size of the resulting string */
! 	if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
! 		return NULL;
  	return result;
  }
--- 1450,1455 ----
  	}
  	/* Fix the size of the resulting string */
! 	if (inlen > 0)
! 		_PyString_Resize(&result, output - output_start);
  	return result;
  }
***************
*** 2426,2430 ****
     as creating a new string object and destroying the old one, only
     more efficiently.  In any case, don't use this if the string may
!    already be known to some other part of the code... */
  
  int
--- 2426,2437 ----
     as creating a new string object and destroying the old one, only
     more efficiently.  In any case, don't use this if the string may
!    already be known to some other part of the code...
!    Note that if there's not enough memory to resize the string, the original
!    string object at *pv is deallocated, *pv is set to NULL, an "out of
!    memory" exception is set, and -1 is returned.  Else (on success) 0 is
!    returned, and the value in *pv may or may not be the same as on input.
!    As always, an extra byte is allocated for a trailing \0 byte (newsize
!    does *not* include that), and a trailing \0 byte is stored.
! */
  
  int

Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.82.2.1
retrieving revision 2.82.2.2
diff -C2 -d -r2.82.2.1 -r2.82.2.2
*** unicodeobject.c	23 May 2001 12:31:25 -0000	2.82.2.1
--- unicodeobject.c	30 Apr 2002 03:58:47 -0000	2.82.2.2
***************
*** 865,869 ****
  
   onError:
-     Py_DECREF(v);
      return NULL;
  }
--- 865,868 ----
***************
*** 1366,1370 ****
  
   onError:
-     Py_DECREF(repr);
      return NULL;
  }
--- 1365,1368 ----
***************
*** 1502,1506 ****
  
   onError:
-     Py_DECREF(repr);
      return NULL;
  }
--- 1500,1503 ----
***************
*** 1590,1595 ****
  	if (ch >= 256) {
  	    if (latin1_encoding_error(&p, &s, errors, 
! 				      "ordinal not in range(256)"))
  		goto onError;
  	}
  	else
--- 1587,1594 ----
  	if (ch >= 256) {
  	    if (latin1_encoding_error(&p, &s, errors, 
! 				      "ordinal not in range(256)")) {
! 		Py_DECREF(repr);
  		goto onError;
+ 	    }
  	}
  	else
***************
*** 1603,1607 ****
  
   onError:
-     Py_DECREF(repr);
      return NULL;
  }
--- 1602,1605 ----
***************
*** 1733,1738 ****
  	if (ch >= 128) {
  	    if (ascii_encoding_error(&p, &s, errors, 
! 				      "ordinal not in range(128)"))
  		goto onError;
  	}
  	else
--- 1731,1738 ----
  	if (ch >= 128) {
  	    if (ascii_encoding_error(&p, &s, errors, 
! 				      "ordinal not in range(128)")) {
! 		Py_DECREF(repr);
  		goto onError;
+ 	    }
  	}
  	else
***************
*** 1746,1750 ****
  
   onError:
-     Py_DECREF(repr);
      return NULL;
  }
--- 1746,1749 ----
***************
*** 2019,2023 ****
  	w = PyInt_FromLong((long)ch);
  	if (w == NULL)
! 	    goto onError;
  	x = PyObject_GetItem(mapping, w);
  	Py_DECREF(w);
--- 2018,2022 ----
  	w = PyInt_FromLong((long)ch);
  	if (w == NULL)
! 	    goto onErrorDecref;
  	x = PyObject_GetItem(mapping, w);
  	Py_DECREF(w);
***************
*** 2029,2033 ****
  		Py_INCREF(x);
  	    } else
! 		goto onError;
  	}
  
--- 2028,2032 ----
  		Py_INCREF(x);
  	    } else
! 		goto onErrorDecref;
  	}
  
***************
*** 2039,2043 ****
  				"character mapping must be in range(256)");
  		Py_DECREF(x);
! 		goto onError;
  	    }
  	    *s++ = (char)value;
--- 2038,2042 ----
  				"character mapping must be in range(256)");
  		Py_DECREF(x);
! 		goto onErrorDecref;
  	    }
  	    *s++ = (char)value;
***************
*** 2048,2052 ****
  				       "character maps to <undefined>")) {
  		Py_DECREF(x);
! 		goto onError;
  	    }
  	}
--- 2047,2051 ----
  				       "character maps to <undefined>")) {
  		Py_DECREF(x);
! 		goto onErrorDecref;
  	    }
  	}
***************
*** 2067,2071 ****
  		    extrachars += needed;
  		    if (_PyString_Resize(&v, PyString_GET_SIZE(v) + needed)) {
! 			Py_DECREF(x);
  			goto onError;
  		    }
--- 2066,2070 ----
  		    extrachars += needed;
  		    if (_PyString_Resize(&v, PyString_GET_SIZE(v) + needed)) {
! 			Py_DECREF(x); 
  			goto onError;
  		    }
***************
*** 2085,2089 ****
  		  "character mapping must return integer, None or unicode");
  	    Py_DECREF(x);
! 	    goto onError;
  	}
  	Py_DECREF(x);
--- 2084,2088 ----
  		  "character mapping must return integer, None or unicode");
  	    Py_DECREF(x);
! 	    goto onErrorDecref;
  	}
  	Py_DECREF(x);
***************
*** 2094,2099 ****
      return v;
  
!  onError:
      Py_DECREF(v);
      return NULL;
  }
--- 2093,2099 ----
      return v;
  
!  onErrorDecref:
      Py_DECREF(v);
+  onError:
      return NULL;
  }