Repair widespread misuse of _PyString_Resize. Since it's clear people
don't understand how this function works, also beefed up the docs. The
most common usage error is of this form (often spread out across gotos):
if (_PyString_Resize(&s, n) < 0) {
Py_DECREF(s);
s = NULL;
goto outtahere;
}
The error is that if _PyString_Resize runs out of memory, it automatically
decrefs the input string object s (which also deallocates it, since its
refcount must be 1 upon entry), and sets s to NULL. So if the "if"
branch ever triggers, it's an error to call Py_DECREF(s): s is already
NULL! A correct way to write the above is the simpler (and intended)
if (_PyString_Resize(&s, n) < 0)
goto outtahere;
Bugfix candidate.
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index f5ab2b6..1b05e40 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -331,8 +331,8 @@
Py_DECREF(buf);
return PySSL_SetError(self, count);
}
- if (count != len && _PyString_Resize(&buf, count) < 0)
- return NULL;
+ if (count != len)
+ _PyString_Resize(&buf, count);
return buf;
}
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index 2ffba48..a6c5e9d 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -1252,14 +1252,8 @@
*p++ = (char) ch;
}
*p = '\0';
- if (_PyString_Resize(&repr, p - q))
- goto onError;
-
+ _PyString_Resize(&repr, p - q);
return repr;
-
- onError:
- Py_DECREF(repr);
- return NULL;
}
diff --git a/Modules/cdmodule.c b/Modules/cdmodule.c
index b977277..25add3e 100644
--- a/Modules/cdmodule.c
+++ b/Modules/cdmodule.c
@@ -251,8 +251,7 @@
return NULL;
}
if (n < numframes)
- if (_PyString_Resize(&result, n * sizeof(CDFRAME)))
- return NULL;
+ _PyString_Resize(&result, n * sizeof(CDFRAME));
return result;
}
diff --git a/Modules/clmodule.c b/Modules/clmodule.c
index ef3d77a..70e8f8e 100644
--- a/Modules/clmodule.c
+++ b/Modules/clmodule.c
@@ -135,8 +135,7 @@
}
if (compressedBufferSize < frameBufferSize)
- if (_PyString_Resize(&compressedBuffer, compressedBufferSize))
- return NULL;
+ _PyString_Resize(&compressedBuffer, compressedBufferSize);
return compressedBuffer;
}
diff --git a/Modules/linuxaudiodev.c b/Modules/linuxaudiodev.c
index fa2e441..7d4abc9 100644
--- a/Modules/linuxaudiodev.c
+++ b/Modules/linuxaudiodev.c
@@ -158,8 +158,7 @@
return NULL;
}
self->x_icount += count;
- if (_PyString_Resize(&rv, count) == -1)
- return NULL;
+ _PyString_Resize(&rv, count);
return rv;
}
diff --git a/Modules/regexmodule.c b/Modules/regexmodule.c
index d449604..4c7035e 100644
--- a/Modules/regexmodule.c
+++ b/Modules/regexmodule.c
@@ -516,11 +516,8 @@
return NULL;
}
/* _PyString_Resize() decrements npattern on failure */
- if (_PyString_Resize(&npattern, n - v) == 0)
- return npattern;
- else {
- return NULL;
- }
+ _PyString_Resize(&npattern, n - v);
+ return npattern;
}
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 53952fc..21fcab0 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1402,8 +1402,8 @@
Py_DECREF(buf);
return s->errorhandler();
}
- if (n != len && _PyString_Resize(&buf, n) < 0)
- return NULL;
+ if (n != len)
+ _PyString_Resize(&buf, n);
return buf;
}
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c
index 0d5b75c..9a68b20 100644
--- a/Modules/stropmodule.c
+++ b/Modules/stropmodule.c
@@ -215,10 +215,8 @@
}
slen = PyString_GET_SIZE(item);
while (reslen + slen + seplen >= sz) {
- if (_PyString_Resize(&res, sz * 2)) {
- Py_DECREF(res);
+ if (_PyString_Resize(&res, sz * 2) < 0)
return NULL;
- }
sz *= 2;
p = PyString_AsString(res) + reslen;
}
@@ -231,10 +229,7 @@
p += slen;
reslen += slen;
}
- if (_PyString_Resize(&res, reslen)) {
- Py_DECREF(res);
- res = NULL;
- }
+ _PyString_Resize(&res, reslen);
return res;
}
@@ -257,8 +252,7 @@
}
slen = PyString_GET_SIZE(item);
while (reslen + slen + seplen >= sz) {
- if (_PyString_Resize(&res, sz * 2)) {
- Py_DECREF(res);
+ if (_PyString_Resize(&res, sz * 2) < 0) {
Py_DECREF(item);
return NULL;
}
@@ -275,10 +269,7 @@
reslen += slen;
Py_DECREF(item);
}
- if (_PyString_Resize(&res, reslen)) {
- Py_DECREF(res);
- res = NULL;
- }
+ _PyString_Resize(&res, reslen);
return res;
}
@@ -989,8 +980,8 @@
return input_obj;
}
/* Fix the size of the resulting string */
- if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
- return NULL;
+ if (inlen > 0)
+ _PyString_Resize(&result, output - output_start);
return result;
}
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index a3891f7..cfb71ae 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -255,9 +255,8 @@
/* fall through */
case(Z_OK):
/* need more memory */
- if (_PyString_Resize(&result_str, r_strlen << 1) == -1) {
+ if (_PyString_Resize(&result_str, r_strlen << 1) < 0) {
inflateEnd(&zst);
- result_str = NULL;
goto error;
}
zst.next_out = (unsigned char *)PyString_AS_STRING(result_str) \
@@ -414,10 +413,8 @@
/* while Z_OK and the output buffer is full, there might be more output,
so extend the output buffer and try again */
while (err == Z_OK && self->zst.avail_out == 0) {
- if (_PyString_Resize(&RetVal, length << 1) == -1) {
- RetVal = NULL;
+ if (_PyString_Resize(&RetVal, length << 1) < 0)
goto error;
- }
self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ length;
self->zst.avail_out = length;
@@ -438,9 +435,7 @@
RetVal = NULL;
goto error;
}
- if (_PyString_Resize(&RetVal,
- self->zst.total_out - start_total_out) < 0)
- RetVal = NULL;
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
error:
LEAVE_ZLIB
@@ -510,10 +505,8 @@
if (max_length && length > max_length)
length = max_length;
- if (_PyString_Resize(&RetVal, length) == -1) {
- RetVal = NULL;
+ if (_PyString_Resize(&RetVal, length) < 0)
goto error;
- }
self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ old_length;
self->zst.avail_out = length - old_length;
@@ -561,8 +554,7 @@
goto error;
}
- if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0)
- RetVal = NULL;
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
error:
LEAVE_ZLIB
@@ -612,10 +604,8 @@
/* while Z_OK and the output buffer is full, there might be more output,
so extend the output buffer and try again */
while (err == Z_OK && self->zst.avail_out == 0) {
- if (_PyString_Resize(&RetVal, length << 1) == -1) {
- RetVal = NULL;
+ if (_PyString_Resize(&RetVal, length << 1) < 0)
goto error;
- }
self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \
+ length;
self->zst.avail_out = length;
@@ -651,8 +641,7 @@
goto error;
}
- if (_PyString_Resize(&RetVal, self->zst.total_out - start_total_out) < 0)
- RetVal = NULL;
+ _PyString_Resize(&RetVal, self->zst.total_out - start_total_out);
error:
LEAVE_ZLIB