v1-0002-jsonb_plperl-Replace-reference-unwinding-loop-wit.patch
text/x-patch
Filename: v1-0002-jsonb_plperl-Replace-reference-unwinding-loop-wit.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v1-0002
Subject: jsonb_plperl: Replace reference-unwinding loop with recursion
| File | + | − |
|---|---|---|
| contrib/jsonb_plperl/jsonb_plperl.c | 15 | 3 |
From 4a600d76b7e4ec50d0e91da291da4fc9e00deeaf Mon Sep 17 00:00:00 2001
From: Aleksander Alekseev <aleksander@tigerdata.com>
Date: Tue, 16 Jun 2026 15:54:08 +0300
Subject: [PATCH v1 2/2] jsonb_plperl: Replace reference-unwinding loop with
recursion
SV_to_JsonbValue() used a while loop to dereference chains of Perl
references before processing the underlying value. This loop had no
protection against circular reference chains (e.g. $x = \$x), causing
the backend to spin indefinitely.
Replace the loop with a small recursive helper SV_deref() that calls
check_stack_depth() on each step. This makes circular and pathologically
deep reference chains raise "stack depth limit exceeded" instead of
hanging the backend, consistent with how jsonb_plpython handles circular
Python object references.
Author: Aleksander Alekseev <aleksander@tigerdata.com>
Reviewed-by: TODO FIXME
Discussion: TODO FIXME
---
contrib/jsonb_plperl/jsonb_plperl.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c
index fdcec7760da..40c283d3132 100644
--- a/contrib/jsonb_plperl/jsonb_plperl.c
+++ b/contrib/jsonb_plperl/jsonb_plperl.c
@@ -176,6 +176,20 @@ HV_to_JsonbValue(HV *obj, JsonbInState *jsonb_state)
pushJsonbValue(jsonb_state, WJB_END_OBJECT, NULL);
}
+/*
+ * Recursively dereference a Perl reference to reach the underlying value.
+ * Using recursion rather than a loop lets check_stack_depth() detect
+ * circular reference chains.
+ */
+static SV *
+SV_deref(SV *in)
+{
+ check_stack_depth();
+ if (SvROK(in))
+ return SV_deref(SvRV(in));
+ return in;
+}
+
static void
SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem)
{
@@ -184,9 +198,7 @@ SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem)
check_stack_depth();
- /* Dereference references recursively. */
- while (SvROK(in))
- in = SvRV(in);
+ in = SV_deref(in);
switch (SvTYPE(in))
{
--
2.43.0