[Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.142,2.143

Tim Peters tim_one@users.sourceforge.net
2001年12月02日 17:55:40 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv31521/python/Objects
Modified Files:
	stringobject.c 
Log Message:
PyString_FromFormatV, string_repr: document why these use sprintf
instead of PyOS_snprintf; add some relevant comments and asserts.
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.142
retrieving revision 2.143
diff -C2 -d -r2.142 -r2.143
*** stringobject.c	2001年12月02日 18:09:41	2.142
--- stringobject.c	2001年12月03日 01:55:38	2.143
***************
*** 180,184 ****
 			 width. although only %d is supported (see
 			 "expand" section below), others can be easily
! 			 add */
 			if (*f == 'l' && *(f+1) == 'd')
 				++f;
--- 180,184 ----
 			 width. although only %d is supported (see
 			 "expand" section below), others can be easily
! 			 added */
 			if (*f == 'l' && *(f+1) == 'd')
 				++f;
***************
*** 193,198 ****
 			case 'd': case 'i': case 'x':
 				(void) va_arg(count, int);
! 				/* 20 bytes should be enough to hold a 64-bit
! 				 integer */
 				n += 20;
 				break;
--- 193,199 ----
 			case 'd': case 'i': case 'x':
 				(void) va_arg(count, int);
! 				/* 20 bytes is enough to hold a 64-bit
! 				 integer. Decimal takes the most space.
! 				 This isn't enough for octal. */
 				n += 20;
 				break;
***************
*** 206,209 ****
--- 207,211 ----
 				 * 0xffffffffffffffff
 				 * so 19 characters is enough.
+ 				 * XXX I count 18 -- what's the extra for?
 				 */
 				n += 19;
***************
*** 224,227 ****
--- 226,231 ----
 expand:
 	/* step 2: fill the buffer */
+ 	/* Since we've analyzed how much space we need for the worst case,
+ 	 use sprintf directly instead of the slower PyOS_snprintf. */
 	string = PyString_FromStringAndSize(NULL, n);
 	if (!string)
***************
*** 641,647 ****
 			quote = '"';
 
! 		p = ((PyStringObject *)v)->ob_sval;
 		*p++ = quote;
 		for (i = 0; i < op->ob_size; i++) {
 			c = op->ob_sval[i];
 			if (c == quote || c == '\\')
--- 645,654 ----
 			quote = '"';
 
! 		p = PyString_AS_STRING(v);
 		*p++ = quote;
 		for (i = 0; i < op->ob_size; i++) {
+ 			/* There's at least enough room for a hex escape
+ 			 and a closing quote. */
+ 			assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
 			c = op->ob_sval[i];
 			if (c == quote || c == '\\')
***************
*** 654,657 ****
--- 661,667 ----
 				*p++ = '\\', *p++ = 'r';
 			else if (c < ' ' || c >= 0x7f) {
+ 				/* For performance, we don't want to call
+ 				 PyOS_snprintf here (extra layers of
+ 				 function call). */
 				sprintf(p, "\\x%02x", c & 0xff);
 p += 4;
***************
*** 660,667 ****
 				*p++ = c;
 		}
 		*p++ = quote;
 		*p = '0円';
 		_PyString_Resize(
! 			&v, (int) (p - ((PyStringObject *)v)->ob_sval));
 		return v;
 	}
--- 670,678 ----
 				*p++ = c;
 		}
+ 		assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
 		*p++ = quote;
 		*p = '0円';
 		_PyString_Resize(
! 			&v, (int) (p - PyString_AS_STRING(v)));
 		return v;
 	}

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