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
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index dc41122..246e080 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -743,7 +743,7 @@
 	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 @@
 	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 @@
 				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);