Skip to content

Commit f71cd53

Browse files
authored
gh-110572: Fix potential leaks in test_*_code in _testcapi/getargs.c (GH-110573)
1 parent e136e2d commit f71cd53

File tree

1 file changed

+57
-33
lines changed

1 file changed

+57
-33
lines changed

Modules/_testcapi/getargs.c

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -359,68 +359,83 @@ getargs_K(PyObject *self, PyObject *args)
359359
static PyObject *
360360
test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored))
361361
{
362-
PyObject *tuple, *num;
363-
unsigned long value;
364-
365-
tuple = PyTuple_New(1);
362+
PyObject *tuple = PyTuple_New(1);
366363
if (tuple == NULL) {
367364
return NULL;
368365
}
369366

370367
/* a number larger than ULONG_MAX even on 64-bit platforms */
371-
num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
368+
PyObject *num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
372369
if (num == NULL) {
373-
return NULL;
370+
goto error;
374371
}
375372

376-
value = PyLong_AsUnsignedLongMask(num);
377-
if (value != ULONG_MAX) {
373+
unsigned long value = PyLong_AsUnsignedLongMask(num);
374+
if (value == (unsigned long)-1 && PyErr_Occurred()) {
375+
Py_DECREF(num);
376+
goto error;
377+
}
378+
else if (value != ULONG_MAX) {
379+
Py_DECREF(num);
378380
PyErr_SetString(PyExc_AssertionError,
379381
"test_k_code: "
380382
"PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");
381-
return NULL;
383+
goto error;
382384
}
383385

384386
PyTuple_SET_ITEM(tuple, 0, num);
385387

386388
value = 0;
387389
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
388-
return NULL;
390+
goto error;
389391
}
390392
if (value != ULONG_MAX) {
391393
PyErr_SetString(PyExc_AssertionError,
392394
"test_k_code: k code returned wrong value for long 0xFFF...FFF");
393-
return NULL;
395+
goto error;
394396
}
395397

396-
Py_DECREF(num);
398+
Py_DECREF(tuple); // also clears `num`
399+
tuple = PyTuple_New(1);
400+
if (tuple == NULL) {
401+
return NULL;
402+
}
397403
num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16);
398404
if (num == NULL) {
399-
return NULL;
405+
goto error;
400406
}
401407

402408
value = PyLong_AsUnsignedLongMask(num);
403-
if (value != (unsigned long)-0x42) {
409+
if (value == (unsigned long)-1 && PyErr_Occurred()) {
410+
Py_DECREF(num);
411+
goto error;
412+
}
413+
else if (value != (unsigned long)-0x42) {
414+
Py_DECREF(num);
404415
PyErr_SetString(PyExc_AssertionError,
405416
"test_k_code: "
406417
"PyLong_AsUnsignedLongMask() returned wrong value for long -0xFFF..000042");
407-
return NULL;
418+
goto error;
408419
}
409420

410421
PyTuple_SET_ITEM(tuple, 0, num);
411422

412423
value = 0;
413424
if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) {
414-
return NULL;
425+
goto error;
415426
}
416427
if (value != (unsigned long)-0x42) {
417428
PyErr_SetString(PyExc_AssertionError,
418429
"test_k_code: k code returned wrong value for long -0xFFF..000042");
419-
return NULL;
430+
goto error;
420431
}
421432

422433
Py_DECREF(tuple);
423434
Py_RETURN_NONE;
435+
436+
error:
437+
Py_DECREF(tuple);
438+
return NULL;
424439
}
425440

426441
static PyObject *
@@ -710,51 +725,56 @@ getargs_et_hash(PyObject *self, PyObject *args)
710725
static PyObject *
711726
test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored))
712727
{
713-
PyObject *tuple, *num;
714-
long long value;
715-
716-
tuple = PyTuple_New(1);
728+
PyObject *tuple = PyTuple_New(1);
717729
if (tuple == NULL) {
718730
return NULL;
719731
}
720732

721-
num = PyLong_FromLong(42);
733+
PyObject *num = PyLong_FromLong(42);
722734
if (num == NULL) {
723-
return NULL;
735+
goto error;
724736
}
725737

726738
PyTuple_SET_ITEM(tuple, 0, num);
727739

728-
value = -1;
740+
long long value = -1;
729741
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
730-
return NULL;
742+
goto error;
731743
}
732744
if (value != 42) {
733745
PyErr_SetString(PyExc_AssertionError,
734746
"test_L_code: L code returned wrong value for long 42");
735-
return NULL;
747+
goto error;
736748
}
737749

738-
Py_DECREF(num);
750+
Py_DECREF(tuple); // also clears `num`
751+
tuple = PyTuple_New(1);
752+
if (tuple == NULL) {
753+
return NULL;
754+
}
739755
num = PyLong_FromLong(42);
740756
if (num == NULL) {
741-
return NULL;
757+
goto error;
742758
}
743759

744760
PyTuple_SET_ITEM(tuple, 0, num);
745761

746762
value = -1;
747763
if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) {
748-
return NULL;
764+
goto error;
749765
}
750766
if (value != 42) {
751767
PyErr_SetString(PyExc_AssertionError,
752768
"test_L_code: L code returned wrong value for int 42");
753-
return NULL;
769+
goto error;
754770
}
755771

756772
Py_DECREF(tuple);
757773
Py_RETURN_NONE;
774+
775+
error:
776+
Py_DECREF(tuple);
777+
return NULL;
758778
}
759779

760780
/* Test the s and z codes for PyArg_ParseTuple.
@@ -771,7 +791,7 @@ test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored))
771791
PyObject *obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"),
772792
"latin-1", NULL);
773793
if (obj == NULL) {
774-
return NULL;
794+
goto error;
775795
}
776796

777797
PyTuple_SET_ITEM(tuple, 0, obj);
@@ -781,15 +801,19 @@ test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored))
781801
*/
782802
char *value;
783803
if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) {
784-
return NULL;
804+
goto error;
785805
}
786806

787807
if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) {
788-
return NULL;
808+
goto error;
789809
}
790810

791811
Py_DECREF(tuple);
792812
Py_RETURN_NONE;
813+
814+
error:
815+
Py_DECREF(tuple);
816+
return NULL;
793817
}
794818

795819
static PyObject *

0 commit comments

Comments
 (0)