From 88887aa38eee7d6c12c5f5a108b6a0a4302d7ae5 Mon Sep 17 00:00:00 2001
From: Jeremy Hylton <jeremy@alum.mit.edu>
Date: Tue, 11 Jul 2000 20:55:38 +0000
Subject: [PATCH] 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

---
 Lib/test/string_tests.py |  3 +++
 Objects/stringobject.c   | 15 +++++++++------
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index e9168ef807..d4041bec4a 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -123,6 +123,9 @@ def run_method_tests(test):
     test('join', '.', u'a.b.c', ['a', u'b', 'c'])
     test('join', '.', u'a.b.c', ['a', 'b', u'c'])
     test('join', '.', TypeError, ['a', u'b', 3])
+    for i in [5, 25, 125]:
+        test('join', '-', ((('a' * i) + '-') * i)[:-1],
+             ['a' * i] * i)
 
     test('join', ' ', TypeError, BadSeq1())
     test('join', ' ', 'a b c', BadSeq2())
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index dc41122c8a..246e08061b 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -743,7 +743,7 @@ string_join(PyStringObject *self, PyObject *args)
 	char *p;
 	int seqlen = 0;
 	int sz = 100;
-	int i, slen;
+	int i, slen, sz_incr;
 	PyObject *orig, *seq, *item;
 
 	if (!PyArg_ParseTuple(args, "O:join", &orig))
@@ -770,7 +770,7 @@ string_join(PyStringObject *self, PyObject *args)
 	if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
 		goto finally;
 
-	p = PyString_AsString(res);
+	p = PyString_AS_STRING(res);
 
 	for (i = 0; i < seqlen; i++) {
 		item = PySequence_Fast_GET_ITEM(seq, i);
@@ -781,17 +781,20 @@ string_join(PyStringObject *self, PyObject *args)
 				return PyUnicode_Join((PyObject *)self, seq);
 			}
 			PyErr_Format(PyExc_TypeError,
-			     "sequence item %i: expected string, %.80s found",
+				     "sequence item %i: expected string,"
+				     " %.80s found",
 				     i, item->ob_type->tp_name);
 			goto finally;
 		}
 		slen = PyString_GET_SIZE(item);
 		while (reslen + slen + seplen >= sz) {
-			if (_PyString_Resize(&res, sz*2)) {
+			/* at least double the size of the string */
+			sz_incr = slen + seplen > sz ? slen + seplen : sz;
+			if (_PyString_Resize(&res, sz + sz_incr)) {
 				goto finally;
 			}
-			sz *= 2;
-			p = PyString_AsString(res) + reslen;
+			sz += sz_incr;
+			p = PyString_AS_STRING(res) + reslen;
 		}
 		if (i > 0) {
 			memcpy(p, sep, seplen);
-- 
2.40.0