mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
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:
parent
422cc7ffec
commit
993952bfb2
1 changed files with 12 additions and 21 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue