Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 013142a

Browse files
committed
fix nasty bug in resizing (formatstring)
1 parent e59214e commit 013142a

1 file changed

Lines changed: 98 additions & 18 deletions

File tree

Objects/stringobject.c

Lines changed: 98 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***********************************************************
2-
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
2+
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
33
Amsterdam, The Netherlands.
44
55
All Rights Reserved
@@ -26,6 +26,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2626

2727
#include "allobjects.h"
2828

29+
#include <ctype.h>
30+
2931
#ifdef COUNT_ALLOCS
3032
int null_strings, one_strings;
3133
#endif
@@ -428,11 +430,11 @@ string_hash(a)
428430
}
429431

430432
static sequence_methods string_as_sequence = {
431-
string_length, /*sq_length*/
432-
string_concat, /*sq_concat*/
433-
string_repeat, /*sq_repeat*/
434-
string_item, /*sq_item*/
435-
string_slice, /*sq_slice*/
433+
(inquiry)string_length, /*sq_length*/
434+
(binaryfunc)string_concat, /*sq_concat*/
435+
(intargfunc)string_repeat, /*sq_repeat*/
436+
(intargfunc)string_item, /*sq_item*/
437+
(intintargfunc)string_slice, /*sq_slice*/
436438
0, /*sq_ass_item*/
437439
0, /*sq_ass_slice*/
438440
};
@@ -443,16 +445,16 @@ typeobject Stringtype = {
443445
"string",
444446
sizeof(stringobject),
445447
sizeof(char),
446-
string_dealloc, /*tp_dealloc*/
447-
string_print, /*tp_print*/
448+
(destructor)string_dealloc, /*tp_dealloc*/
449+
(printfunc)string_print, /*tp_print*/
448450
0, /*tp_getattr*/
449451
0, /*tp_setattr*/
450-
string_compare, /*tp_compare*/
451-
string_repr, /*tp_repr*/
452+
(cmpfunc)string_compare, /*tp_compare*/
453+
(reprfunc)string_repr, /*tp_repr*/
452454
0, /*tp_as_number*/
453455
&string_as_sequence, /*tp_as_sequence*/
454456
0, /*tp_as_mapping*/
455-
string_hash, /*tp_hash*/
457+
(hashfunc)string_hash, /*tp_hash*/
456458
};
457459

458460
void
@@ -461,13 +463,28 @@ joinstring(pv, w)
461463
register object *w;
462464
{
463465
register object *v;
464-
if (*pv == NULL || w == NULL || !is_stringobject(*pv))
466+
if (*pv == NULL)
467+
return;
468+
if (w == NULL || !is_stringobject(*pv)) {
469+
DECREF(*pv);
470+
*pv = NULL;
465471
return;
472+
}
466473
v = string_concat((stringobject *) *pv, w);
467474
DECREF(*pv);
468475
*pv = v;
469476
}
470477

478+
void
479+
joinstring_decref(pv, w)
480+
register object **pv;
481+
register object *w;
482+
{
483+
joinstring(pv, w);
484+
XDECREF(w);
485+
}
486+
487+
471488
/* The following function breaks the notion that strings are immutable:
472489
it changes the size of a string. We get away with this only if there
473490
is only one module referencing the object. You can also think of it
@@ -596,6 +613,27 @@ formatchar(v)
596613
return buf;
597614
}
598615

616+
/* XXX this could be moved to object.c */
617+
static object *
618+
get_mapping_item(mo, ko)
619+
object *mo;
620+
object *ko;
621+
{
622+
mapping_methods *mm = mo->ob_type->tp_as_mapping;
623+
object *val;
624+
625+
if (!mm || !mm->mp_subscript) {
626+
err_setstr(TypeError, "subscript not implemented");
627+
return NULL;
628+
}
629+
630+
val = (*mm->mp_subscript)(mo, ko);
631+
XDECREF(val); /* still in mapping */
632+
633+
return val;
634+
}
635+
636+
599637
/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
600638

601639
object *
@@ -606,6 +644,7 @@ formatstring(format, args)
606644
char *fmt, *res;
607645
int fmtcnt, rescnt, reslen, arglen, argidx;
608646
object *result;
647+
object *dict = NULL;
609648
if (format == NULL || !is_stringobject(format) || args == NULL) {
610649
err_badcall();
611650
return NULL;
@@ -625,6 +664,8 @@ formatstring(format, args)
625664
arglen = -1;
626665
argidx = -2;
627666
}
667+
if (args->ob_type->tp_as_mapping)
668+
dict = args;
628669
while (--fmtcnt >= 0) {
629670
if (*fmt != '%') {
630671
if (--rescnt < 0) {
@@ -633,6 +674,7 @@ formatstring(format, args)
633674
if (resizestring(&result, reslen) < 0)
634675
return NULL;
635676
res = getstringvalue(result) + reslen - rescnt;
677+
--rescnt;
636678
}
637679
*res++ = *fmt++;
638680
}
@@ -646,9 +688,43 @@ formatstring(format, args)
646688
int c = '\0';
647689
int fill;
648690
object *v;
691+
object *temp = NULL;
649692
char *buf;
650693
int sign;
651694
int len;
695+
if (*fmt == '(') {
696+
char *keystart;
697+
int keylen;
698+
object *key;
699+
700+
if (dict == NULL) {
701+
err_setstr(TypeError,
702+
"format requires a mapping");
703+
goto error;
704+
}
705+
++fmt;
706+
--fmtcnt;
707+
keystart = fmt;
708+
while (--fmtcnt >= 0 && *fmt != ')')
709+
fmt++;
710+
keylen = fmt - keystart;
711+
++fmt;
712+
if (fmtcnt < 0) {
713+
err_setstr(ValueError,
714+
"incomplete format key");
715+
goto error;
716+
}
717+
key = newsizedstringobject(keystart, keylen);
718+
if (key == NULL)
719+
goto error;
720+
args = get_mapping_item(dict, key);
721+
DECREF(key);
722+
if (args == NULL) {
723+
goto error;
724+
}
725+
arglen = -1;
726+
argidx = -2;
727+
}
652728
while (--fmtcnt >= 0) {
653729
switch (c = *fmt++) {
654730
case '-': flags |= F_LJUST; continue;
@@ -745,13 +821,11 @@ formatstring(format, args)
745821
len = 1;
746822
break;
747823
case 's':
748-
if (!is_stringobject(v)) {
749-
err_setstr(TypeError,
750-
"%s wants string");
824+
temp = strobject(v);
825+
if (temp == NULL)
751826
goto error;
752-
}
753-
buf = getstringvalue(v);
754-
len = getstringsize(v);
827+
buf = getstringvalue(temp);
828+
len = getstringsize(temp);
755829
if (prec >= 0 && len > prec)
756830
len = prec;
757831
break;
@@ -839,6 +913,12 @@ formatstring(format, args)
839913
--rescnt;
840914
*res++ = ' ';
841915
}
916+
if (dict && (argidx < arglen)) {
917+
err_setstr(TypeError,
918+
"not all arguments converted");
919+
goto error;
920+
}
921+
XDECREF(temp);
842922
} /* '%' */
843923
} /* until end */
844924
if (argidx < arglen) {

0 commit comments

Comments
 (0)