Skip to content

Commit be580f2

Browse files
committed
Issue #20434 Correct error handlin of _PyString_Resize and _PyBytes_Resize
1 parent 4e0df17 commit be580f2

File tree

6 files changed

+32
-56
lines changed

6 files changed

+32
-56
lines changed

Modules/_io/fileio.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -549,14 +549,8 @@ fileio_readall(fileio *self)
549549
}
550550

551551
if (PyBytes_GET_SIZE(result) < (Py_ssize_t)newsize) {
552-
if (_PyBytes_Resize(&result, newsize) < 0) {
553-
if (total == 0) {
554-
Py_DECREF(result);
555-
return NULL;
556-
}
557-
PyErr_Clear();
558-
break;
559-
}
552+
if (_PyBytes_Resize(&result, newsize) < 0)
553+
return NULL; /* result has been freed */
560554
}
561555
Py_BEGIN_ALLOW_THREADS
562556
errno = 0;
@@ -599,7 +593,6 @@ fileio_readall(fileio *self)
599593
if (PyBytes_GET_SIZE(result) > total) {
600594
if (_PyBytes_Resize(&result, total) < 0) {
601595
/* This should never happen, but just in case */
602-
Py_DECREF(result);
603596
return NULL;
604597
}
605598
}
@@ -656,10 +649,8 @@ fileio_read(fileio *self, PyObject *args)
656649
}
657650

658651
if (n != size) {
659-
if (_PyBytes_Resize(&bytes, n) < 0) {
660-
Py_DECREF(bytes);
652+
if (_PyBytes_Resize(&bytes, n) < 0)
661653
return NULL;
662-
}
663654
}
664655

665656
return (PyObject *) bytes;

Modules/binascii.c

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,10 @@ binascii_b2a_uu(PyObject *self, PyObject *args)
320320
}
321321
*ascii_data++ = '\n'; /* Append a courtesy newline */
322322

323-
if (_PyString_Resize(&rv,
323+
/* rv is cleared on error */
324+
(void)_PyString_Resize(&rv,
324325
(ascii_data -
325-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
326-
Py_DECREF(rv);
327-
rv = NULL;
328-
}
326+
(unsigned char *)PyString_AS_STRING(rv)));
329327
PyBuffer_Release(&pbin);
330328
return rv;
331329
}
@@ -452,10 +450,8 @@ binascii_a2b_base64(PyObject *self, PyObject *args)
452450
** string instead; _PyString_Resize() won't do this for us.
453451
*/
454452
if (bin_len > 0) {
455-
if (_PyString_Resize(&rv, bin_len) < 0) {
456-
Py_DECREF(rv);
457-
rv = NULL;
458-
}
453+
/* rv is cleared on error */
454+
(void)_PyString_Resize(&rv, bin_len);
459455
}
460456
else {
461457
Py_DECREF(rv);
@@ -522,12 +518,10 @@ binascii_b2a_base64(PyObject *self, PyObject *args)
522518
}
523519
*ascii_data++ = '\n'; /* Append a courtesy newline */
524520

525-
if (_PyString_Resize(&rv,
521+
/* rv is cleared on error */
522+
(void)_PyString_Resize(&rv,
526523
(ascii_data -
527-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
528-
Py_DECREF(rv);
529-
rv = NULL;
530-
}
524+
(unsigned char *)PyString_AS_STRING(rv)));
531525
PyBuffer_Release(&pbuf);
532526
return rv;
533527
}
@@ -601,13 +595,10 @@ binascii_a2b_hqx(PyObject *self, PyObject *args)
601595
Py_DECREF(rv);
602596
return NULL;
603597
}
598+
/* rv is cleared on error */
604599
if (_PyString_Resize(&rv,
605600
(bin_data -
606-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
607-
Py_DECREF(rv);
608-
rv = NULL;
609-
}
610-
if (rv) {
601+
(unsigned char *)PyString_AS_STRING(rv))) == 0) {
611602
PyObject *rrv = Py_BuildValue("Oi", rv, done);
612603
PyBuffer_Release(&pascii);
613604
Py_DECREF(rv);
@@ -672,12 +663,10 @@ binascii_rlecode_hqx(PyObject *self, PyObject *args)
672663
}
673664
}
674665
}
675-
if (_PyString_Resize(&rv,
666+
/* rv is cleared on error */
667+
(void)_PyString_Resize(&rv,
676668
(out_data -
677-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
678-
Py_DECREF(rv);
679-
rv = NULL;
680-
}
669+
(unsigned char *)PyString_AS_STRING(rv)));
681670
PyBuffer_Release(&pbuf);
682671
return rv;
683672
}
@@ -729,12 +718,10 @@ binascii_b2a_hqx(PyObject *self, PyObject *args)
729718
leftchar <<= (6-leftbits);
730719
*ascii_data++ = table_b2a_hqx[leftchar & 0x3f];
731720
}
732-
if (_PyString_Resize(&rv,
721+
/* rv is cleared on error */
722+
(void)_PyString_Resize(&rv,
733723
(ascii_data -
734-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
735-
Py_DECREF(rv);
736-
rv = NULL;
737-
}
724+
(unsigned char *)PyString_AS_STRING(rv)));
738725
PyBuffer_Release(&pbin);
739726
return rv;
740727
}
@@ -796,7 +783,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
796783
if ( --out_len_left < 0 ) { \
797784
if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \
798785
if (_PyString_Resize(&rv, 2*out_len) < 0) \
799-
{ Py_DECREF(rv); PyBuffer_Release(&pin); return NULL; } \
786+
{ PyBuffer_Release(&pin); return NULL; } \
800787
out_data = (unsigned char *)PyString_AS_STRING(rv) \
801788
+ out_len; \
802789
out_len_left = out_len-1; \
@@ -846,12 +833,10 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args)
846833
OUTBYTE(in_byte);
847834
}
848835
}
849-
if (_PyString_Resize(&rv,
836+
/* rv is cleared on error */
837+
(void)_PyString_Resize(&rv,
850838
(out_data -
851-
(unsigned char *)PyString_AS_STRING(rv))) < 0) {
852-
Py_DECREF(rv);
853-
rv = NULL;
854-
}
839+
(unsigned char *)PyString_AS_STRING(rv)));
855840
PyBuffer_Release(&pin);
856841
return rv;
857842
}

Modules/bz2module.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,8 @@ BZ2File_readlines(BZ2FileObject *self, PyObject *args)
732732
}
733733
else {
734734
/* Grow the big buffer */
735-
_PyString_Resize(&big_buffer, buffersize);
735+
if (_PyString_Resize(&big_buffer, buffersize))
736+
goto error;
736737
buffer = PyString_AS_STRING(big_buffer);
737738
}
738739
continue;

Objects/bytearrayobject.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -994,10 +994,8 @@ bytearray_repr(PyByteArrayObject *self)
994994
*p++ = *quote_postfix++;
995995
}
996996
*p = '\0';
997-
if (_PyString_Resize(&v, (p - PyString_AS_STRING(v)))) {
998-
Py_DECREF(v);
999-
return NULL;
1000-
}
997+
/* v is cleared on error */
998+
(void)_PyString_Resize(&v, (p - PyString_AS_STRING(v)));
1001999
return v;
10021000
}
10031001
}

Objects/stringobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,8 @@ PyObject *PyString_DecodeEscape(const char *s,
748748
UTF-8 bytes may follow. */
749749
}
750750
}
751-
if (p-buf < newlen && _PyString_Resize(&v, p - buf))
752-
goto failed;
751+
if (p-buf < newlen)
752+
_PyString_Resize(&v, p - buf); /* v is cleared on error */
753753
return v;
754754
failed:
755755
Py_DECREF(v);

PC/_subprocess.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ getenvironment(PyObject* environment)
367367
vsize + 1 + 1;
368368
if (totalsize > PyString_GET_SIZE(out)) {
369369
int offset = p - PyString_AS_STRING(out);
370-
_PyString_Resize(&out, totalsize + 1024);
370+
if (_PyString_Resize(&out, totalsize + 1024))
371+
goto exit;
371372
p = PyString_AS_STRING(out) + offset;
372373
}
373374
memcpy(p, PyString_AS_STRING(key), ksize);
@@ -383,7 +384,7 @@ getenvironment(PyObject* environment)
383384
_PyString_Resize(&out, p - PyString_AS_STRING(out));
384385

385386
/* PyObject_Print(out, stdout, 0); */
386-
387+
exit:
387388
Py_XDECREF(keys);
388389
Py_XDECREF(values);
389390

0 commit comments

Comments
 (0)