Fix obscure bug in string%mapping where the mapping creates its items

on the fly -- there was an unsafe DECREF.  Actually save some lines of
code by using abstract.c:PyObject_GetItem().
This commit is contained in:
Guido van Rossum 1996-05-21 22:44:20 +00:00
parent 422cc7ffec
commit 993952bfb2

View file

@ -613,26 +613,6 @@ 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, ...) */
@ -643,6 +623,7 @@ formatstring(format, args)
{ {
char *fmt, *res; char *fmt, *res;
int fmtcnt, rescnt, reslen, arglen, argidx; int fmtcnt, rescnt, reslen, arglen, argidx;
int args_owned = 0;
object *result; object *result;
object *dict = NULL; object *dict = NULL;
if (format == NULL || !is_stringobject(format) || args == NULL) { if (format == NULL || !is_stringobject(format) || args == NULL) {
@ -692,6 +673,7 @@ formatstring(format, args)
char *buf; char *buf;
int sign; int sign;
int len; int len;
args_owned = 0;
if (*fmt == '(') { if (*fmt == '(') {
char *keystart; char *keystart;
int keylen; int keylen;
@ -717,11 +699,16 @@ formatstring(format, args)
key = newsizedstringobject(keystart, keylen); key = newsizedstringobject(keystart, keylen);
if (key == NULL) if (key == NULL)
goto error; goto error;
args = get_mapping_item(dict, key); if (args_owned) {
DECREF(args);
args_owned = 0;
}
args = PyObject_GetItem(dict, key);
DECREF(key); DECREF(key);
if (args == NULL) { if (args == NULL) {
goto error; goto error;
} }
args_owned = 1;
arglen = -1; arglen = -1;
argidx = -2; argidx = -2;
} }
@ -925,9 +912,13 @@ formatstring(format, args)
err_setstr(TypeError, "not all arguments converted"); err_setstr(TypeError, "not all arguments converted");
goto error; goto error;
} }
if (args_owned)
DECREF(args);
resizestring(&result, reslen - rescnt); resizestring(&result, reslen - rescnt);
return result; return result;
error: error:
DECREF(result); DECREF(result);
if (args_owned)
DECREF(args);
return NULL; return NULL;
} }