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

Skip to content

Commit 88887aa

Browse files
committed
small updates to string_join:
use PyString_AS_STRING macro on local string object when resizing string, make sure resized string will always be big enough split string containing error message across two lines add test to string_tests that causes resizing
1 parent 672fac0 commit 88887aa

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

Lib/test/string_tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ def run_method_tests(test):
123123
test('join', '.', u'a.b.c', ['a', u'b', 'c'])
124124
test('join', '.', u'a.b.c', ['a', 'b', u'c'])
125125
test('join', '.', TypeError, ['a', u'b', 3])
126+
for i in [5, 25, 125]:
127+
test('join', '-', ((('a' * i) + '-') * i)[:-1],
128+
['a' * i] * i)
126129

127130
test('join', ' ', TypeError, BadSeq1())
128131
test('join', ' ', 'a b c', BadSeq2())

Objects/stringobject.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ string_join(PyStringObject *self, PyObject *args)
743743
char *p;
744744
int seqlen = 0;
745745
int sz = 100;
746-
int i, slen;
746+
int i, slen, sz_incr;
747747
PyObject *orig, *seq, *item;
748748

749749
if (!PyArg_ParseTuple(args, "O:join", &orig))
@@ -770,7 +770,7 @@ string_join(PyStringObject *self, PyObject *args)
770770
if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
771771
goto finally;
772772

773-
p = PyString_AsString(res);
773+
p = PyString_AS_STRING(res);
774774

775775
for (i = 0; i < seqlen; i++) {
776776
item = PySequence_Fast_GET_ITEM(seq, i);
@@ -781,17 +781,20 @@ string_join(PyStringObject *self, PyObject *args)
781781
return PyUnicode_Join((PyObject *)self, seq);
782782
}
783783
PyErr_Format(PyExc_TypeError,
784-
"sequence item %i: expected string, %.80s found",
784+
"sequence item %i: expected string,"
785+
" %.80s found",
785786
i, item->ob_type->tp_name);
786787
goto finally;
787788
}
788789
slen = PyString_GET_SIZE(item);
789790
while (reslen + slen + seplen >= sz) {
790-
if (_PyString_Resize(&res, sz*2)) {
791+
/* at least double the size of the string */
792+
sz_incr = slen + seplen > sz ? slen + seplen : sz;
793+
if (_PyString_Resize(&res, sz + sz_incr)) {
791794
goto finally;
792795
}
793-
sz *= 2;
794-
p = PyString_AsString(res) + reslen;
796+
sz += sz_incr;
797+
p = PyString_AS_STRING(res) + reslen;
795798
}
796799
if (i > 0) {
797800
memcpy(p, sep, seplen);

0 commit comments

Comments
 (0)