From eb4209a45852d522166f2ec3299b903850695049 Mon Sep 17 00:00:00 2001
From: Aleksander Alekseev <aleksander@tigerdata.com>
Date: Wed, 17 Jun 2026 13:59:50 +0300
Subject: [PATCH v2] jsonb_plperl, jsonb_plpython: Fix unguarded recursion and
 loops

Add check_stack_depth() to Jsonb_to_SV, SV_to_JsonbValue,
PLyObject_FromJsonbContainer, and PLyObject_ToJsonbValue.  Without
this, deeply nested JSONB values crash the backend with SIGSEGV
instead of raising a proper error.

Also add CHECK_FOR_INTERRUPTS() to the while loop in SV_to_JsonbValue
that dereferences chains of Perl references, so that a circular
reference (e.g. $x = \$x) can be cancelled by the user instead of
spinning indefinitely.

Author: Aleksander Alekseev <aleksander@tigerdata.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAJ7c6TPbjkzUk4qJ5dHvDNEz0hBuFue3A-XWz_%3D897z%2BBC%2Bz8A%40mail.gmail.com
---
 contrib/jsonb_plperl/jsonb_plperl.c     | 8 ++++++++
 contrib/jsonb_plpython/jsonb_plpython.c | 5 +++++
 2 files changed, 13 insertions(+)

diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c
index f8e4a584fdd..c0d3b521141 100644
--- a/contrib/jsonb_plperl/jsonb_plperl.c
+++ b/contrib/jsonb_plperl/jsonb_plperl.c
@@ -3,6 +3,7 @@
 #include <math.h>
 
 #include "fmgr.h"
+#include "miscadmin.h"
 #include "plperl.h"
 #include "utils/fmgrprotos.h"
 #include "utils/jsonb.h"
@@ -66,6 +67,8 @@ Jsonb_to_SV(JsonbContainer *jsonb)
 	JsonbIterator *it;
 	JsonbIteratorToken r;
 
+	check_stack_depth();
+
 	it = JsonbIteratorInit(jsonb);
 	r = JsonbIteratorNext(&it, &v, true);
 
@@ -179,9 +182,14 @@ SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem)
 	dTHX;
 	JsonbValue	out;			/* result */
 
+	check_stack_depth();
+
 	/* Dereference references recursively. */
 	while (SvROK(in))
+	{
+		CHECK_FOR_INTERRUPTS();
 		in = SvRV(in);
+	}
 
 	switch (SvTYPE(in))
 	{
diff --git a/contrib/jsonb_plpython/jsonb_plpython.c b/contrib/jsonb_plpython/jsonb_plpython.c
index 4de75a04e76..f6eddb81c48 100644
--- a/contrib/jsonb_plpython/jsonb_plpython.c
+++ b/contrib/jsonb_plpython/jsonb_plpython.c
@@ -1,5 +1,6 @@
 #include "postgres.h"
 
+#include "miscadmin.h"
 #include "plpy_elog.h"
 #include "plpy_typeio.h"
 #include "plpy_util.h"
@@ -143,6 +144,8 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
 	JsonbIterator *it;
 	PyObject   *result;
 
+	check_stack_depth();
+
 	it = JsonbIteratorInit(jsonb);
 	r = JsonbIteratorNext(&it, &v, true);
 
@@ -410,6 +413,8 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbInState *jsonb_state, bool is_elem)
 {
 	JsonbValue *out;
 
+	check_stack_depth();
+
 	if (!PyUnicode_Check(obj))
 	{
 		if (PySequence_Check(obj))
-- 
2.43.0

