Kaydet (Commit) 013142a9 authored tarafından Guido van Rossum's avatar Guido van Rossum

fix nasty bug in resizing (formatstring)

üst e59214ed
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
...@@ -26,6 +26,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -26,6 +26,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h" #include "allobjects.h"
#include <ctype.h>
#ifdef COUNT_ALLOCS #ifdef COUNT_ALLOCS
int null_strings, one_strings; int null_strings, one_strings;
#endif #endif
...@@ -428,11 +430,11 @@ string_hash(a) ...@@ -428,11 +430,11 @@ string_hash(a)
} }
static sequence_methods string_as_sequence = { static sequence_methods string_as_sequence = {
string_length, /*sq_length*/ (inquiry)string_length, /*sq_length*/
string_concat, /*sq_concat*/ (binaryfunc)string_concat, /*sq_concat*/
string_repeat, /*sq_repeat*/ (intargfunc)string_repeat, /*sq_repeat*/
string_item, /*sq_item*/ (intargfunc)string_item, /*sq_item*/
string_slice, /*sq_slice*/ (intintargfunc)string_slice, /*sq_slice*/
0, /*sq_ass_item*/ 0, /*sq_ass_item*/
0, /*sq_ass_slice*/ 0, /*sq_ass_slice*/
}; };
...@@ -443,16 +445,16 @@ typeobject Stringtype = { ...@@ -443,16 +445,16 @@ typeobject Stringtype = {
"string", "string",
sizeof(stringobject), sizeof(stringobject),
sizeof(char), sizeof(char),
string_dealloc, /*tp_dealloc*/ (destructor)string_dealloc, /*tp_dealloc*/
string_print, /*tp_print*/ (printfunc)string_print, /*tp_print*/
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
string_compare, /*tp_compare*/ (cmpfunc)string_compare, /*tp_compare*/
string_repr, /*tp_repr*/ (reprfunc)string_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
&string_as_sequence, /*tp_as_sequence*/ &string_as_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
string_hash, /*tp_hash*/ (hashfunc)string_hash, /*tp_hash*/
}; };
void void
...@@ -461,13 +463,28 @@ joinstring(pv, w) ...@@ -461,13 +463,28 @@ joinstring(pv, w)
register object *w; register object *w;
{ {
register object *v; register object *v;
if (*pv == NULL || w == NULL || !is_stringobject(*pv)) if (*pv == NULL)
return;
if (w == NULL || !is_stringobject(*pv)) {
DECREF(*pv);
*pv = NULL;
return; return;
}
v = string_concat((stringobject *) *pv, w); v = string_concat((stringobject *) *pv, w);
DECREF(*pv); DECREF(*pv);
*pv = v; *pv = v;
} }
void
joinstring_decref(pv, w)
register object **pv;
register object *w;
{
joinstring(pv, w);
XDECREF(w);
}
/* The following function breaks the notion that strings are immutable: /* The following function breaks the notion that strings are immutable:
it changes the size of a string. We get away with this only if there it changes the size of a string. We get away with this only if there
is only one module referencing the object. You can also think of it is only one module referencing the object. You can also think of it
...@@ -596,6 +613,27 @@ formatchar(v) ...@@ -596,6 +613,27 @@ formatchar(v)
return buf; return buf;
} }
/* XXX this could be moved to object.c */
static object *
get_mapping_item(mo, ko)
object *mo;
object *ko;
{
mapping_methods *mm = mo->ob_type->tp_as_mapping;
object *val;
if (!mm || !mm->mp_subscript) {
err_setstr(TypeError, "subscript not implemented");
return NULL;
}
val = (*mm->mp_subscript)(mo, ko);
XDECREF(val); /* still in mapping */
return val;
}
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */ /* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
object * object *
...@@ -606,6 +644,7 @@ formatstring(format, args) ...@@ -606,6 +644,7 @@ formatstring(format, args)
char *fmt, *res; char *fmt, *res;
int fmtcnt, rescnt, reslen, arglen, argidx; int fmtcnt, rescnt, reslen, arglen, argidx;
object *result; object *result;
object *dict = NULL;
if (format == NULL || !is_stringobject(format) || args == NULL) { if (format == NULL || !is_stringobject(format) || args == NULL) {
err_badcall(); err_badcall();
return NULL; return NULL;
...@@ -625,6 +664,8 @@ formatstring(format, args) ...@@ -625,6 +664,8 @@ formatstring(format, args)
arglen = -1; arglen = -1;
argidx = -2; argidx = -2;
} }
if (args->ob_type->tp_as_mapping)
dict = args;
while (--fmtcnt >= 0) { while (--fmtcnt >= 0) {
if (*fmt != '%') { if (*fmt != '%') {
if (--rescnt < 0) { if (--rescnt < 0) {
...@@ -633,6 +674,7 @@ formatstring(format, args) ...@@ -633,6 +674,7 @@ formatstring(format, args)
if (resizestring(&result, reslen) < 0) if (resizestring(&result, reslen) < 0)
return NULL; return NULL;
res = getstringvalue(result) + reslen - rescnt; res = getstringvalue(result) + reslen - rescnt;
--rescnt;
} }
*res++ = *fmt++; *res++ = *fmt++;
} }
...@@ -646,9 +688,43 @@ formatstring(format, args) ...@@ -646,9 +688,43 @@ formatstring(format, args)
int c = '\0'; int c = '\0';
int fill; int fill;
object *v; object *v;
object *temp = NULL;
char *buf; char *buf;
int sign; int sign;
int len; int len;
if (*fmt == '(') {
char *keystart;
int keylen;
object *key;
if (dict == NULL) {
err_setstr(TypeError,
"format requires a mapping");
goto error;
}
++fmt;
--fmtcnt;
keystart = fmt;
while (--fmtcnt >= 0 && *fmt != ')')
fmt++;
keylen = fmt - keystart;
++fmt;
if (fmtcnt < 0) {
err_setstr(ValueError,
"incomplete format key");
goto error;
}
key = newsizedstringobject(keystart, keylen);
if (key == NULL)
goto error;
args = get_mapping_item(dict, key);
DECREF(key);
if (args == NULL) {
goto error;
}
arglen = -1;
argidx = -2;
}
while (--fmtcnt >= 0) { while (--fmtcnt >= 0) {
switch (c = *fmt++) { switch (c = *fmt++) {
case '-': flags |= F_LJUST; continue; case '-': flags |= F_LJUST; continue;
...@@ -745,13 +821,11 @@ formatstring(format, args) ...@@ -745,13 +821,11 @@ formatstring(format, args)
len = 1; len = 1;
break; break;
case 's': case 's':
if (!is_stringobject(v)) { temp = strobject(v);
err_setstr(TypeError, if (temp == NULL)
"%s wants string");
goto error; goto error;
} buf = getstringvalue(temp);
buf = getstringvalue(v); len = getstringsize(temp);
len = getstringsize(v);
if (prec >= 0 && len > prec) if (prec >= 0 && len > prec)
len = prec; len = prec;
break; break;
...@@ -839,6 +913,12 @@ formatstring(format, args) ...@@ -839,6 +913,12 @@ formatstring(format, args)
--rescnt; --rescnt;
*res++ = ' '; *res++ = ' ';
} }
if (dict && (argidx < arglen)) {
err_setstr(TypeError,
"not all arguments converted");
goto error;
}
XDECREF(temp);
} /* '%' */ } /* '%' */
} /* until end */ } /* until end */
if (argidx < arglen) { if (argidx < arglen) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment