From 47557b9f020dc5ea0fe971d2214cc0b7eaafbbc4 Mon Sep 17 00:00:00 2001 From: AZero13 Date: Mon, 8 Dec 2025 00:01:04 -0500 Subject: [PATCH 1/3] gh-142433: Move deref to below the error when checking for laststring Move deref of laststring to below the error checking so the deref is applied after the object in strings is replaced. --- .../2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst | 1 + Objects/templateobject.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst new file mode 100644 index 00000000000000..935203c53a14ed --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst @@ -0,0 +1 @@ +Move deref of laststring to below the error checking so the deref is applied after the object in strings is replaced. diff --git a/Objects/templateobject.c b/Objects/templateobject.c index ac38e4de435d5d..6738aaf23e4288 100644 --- a/Objects/templateobject.c +++ b/Objects/templateobject.c @@ -148,13 +148,13 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (last_was_str) { PyObject *laststring = PyTuple_GET_ITEM(strings, stringsidx - 1); PyObject *concat = PyUnicode_Concat(laststring, item); - Py_DECREF(laststring); if (!concat) { Py_DECREF(strings); Py_DECREF(interpolations); return NULL; } PyTuple_SET_ITEM(strings, stringsidx - 1, concat); + Py_DECREF(laststring); } else { PyTuple_SET_ITEM(strings, stringsidx++, Py_NewRef(item)); From 0113148686b5f4a22e5f5733c4dc1978d76bb104 Mon Sep 17 00:00:00 2001 From: AZero13 Date: Mon, 8 Dec 2025 17:47:22 -0500 Subject: [PATCH 2/3] Fix NEWS message --- .../2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst index 935203c53a14ed..bad31470a25552 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-08-17-34-57.gh-issue-142402.iV0ON3.rst @@ -1 +1,3 @@ -Move deref of laststring to below the error checking so the deref is applied after the object in strings is replaced. +Fix reference counting when adjacent literal parts are merged while constructing +:class:`string.templatelib.Template`, preventing the displaced string object +from leaking. From 74d94624f14ffe687952a542bf39a29fb0a6d85e Mon Sep 17 00:00:00 2001 From: AZero13 Date: Tue, 9 Dec 2025 14:18:07 -0500 Subject: [PATCH 3/3] Add comment clarifying what is happening to laststring --- Objects/templateobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/templateobject.c b/Objects/templateobject.c index 6738aaf23e4288..a05208e4c8fc8e 100644 --- a/Objects/templateobject.c +++ b/Objects/templateobject.c @@ -153,6 +153,7 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(interpolations); return NULL; } + /* Replace laststring with concat */ PyTuple_SET_ITEM(strings, stringsidx - 1, concat); Py_DECREF(laststring); }