fix: hemar: jsonb_value_by_path string copy

This commit is contained in:
2025-05-17 17:59:10 +00:00
parent a17a20b7d6
commit 19ea8992a0
2 changed files with 45 additions and 9 deletions

View File

@@ -1193,16 +1193,17 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
TemplateNode *current = node;
JsonbValue *value;
char *str_value;
char *debug_msg = palloc(1024);
int debug_msg_size = 4096;
char *debug_msg = palloc(debug_msg_size);
while (current)
{
snprintf(debug_msg, 1024, "Rendering node type: %.50s", tnt_to_string(current->type));
snprintf(debug_msg, debug_msg_size, "Rendering node type: %.50s", tnt_to_string(current->type));
switch (current->type)
{
case TEMPLATE_NODE_TEXT:
snprintf(debug_msg, 1024, "%s TEXT: %.50s", debug_msg, current->value->text.content);
snprintf(debug_msg, debug_msg_size, "%s TEXT: %.50s", debug_msg, current->value->text.content);
if (current->value->text.content)
{
/* Preserve whitespace in text nodes */
@@ -1211,10 +1212,11 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
break;
case TEMPLATE_NODE_INTERPOLATE:
snprintf(debug_msg, 1024, "%s INTERPOLATE: %.50s", debug_msg, current->value->interpolate.key);
snprintf(debug_msg, debug_msg_size, "%s INTERPOLATE: %.50s", debug_msg, current->value->interpolate.key);
if (current->value->interpolate.key)
{
/* Get the value from the JSONB context using the path */
elog(DEBUG1, "define: %s", JsonbToCString(NULL, &define->root, VARSIZE_ANY_EXHDR(define)));
value = jsonb_get_by_path_internal(define, current->value->interpolate.key, context);
if (value != NULL)
@@ -1224,6 +1226,7 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
{
case jbvString:
/* Preserve whitespace in string values */
snprintf(debug_msg, debug_msg_size, "%s VALUE: %.50s", debug_msg, value->val.string.val);
appendStringInfoString(result, value->val.string.val);
break;
@@ -1263,17 +1266,17 @@ render_template(TemplateNode *node, Jsonb *define, StringInfo result, MemoryCont
break;
case TEMPLATE_NODE_EXECUTE:
snprintf(debug_msg, 1024, "%s EXECUTE: %.50s", debug_msg, current->value->execute.code);
snprintf(debug_msg, debug_msg_size, "%s EXECUTE: %.50s", debug_msg, current->value->execute.code);
render_execute_tag(current->value->execute.code, define, result, context);
break;
case TEMPLATE_NODE_SECTION:
snprintf(debug_msg, 1024, "%s SECTION: %.50s", debug_msg, current->value->section.iterator);
snprintf(debug_msg, debug_msg_size, "%s SECTION: %.50s", debug_msg, current->value->section.iterator);
/* We'll implement section rendering later */
break;
case TEMPLATE_NODE_INCLUDE:
snprintf(debug_msg, 1024, "%s INCLUDE: %.50s", debug_msg, current->value->include.key);
snprintf(debug_msg, debug_msg_size, "%s INCLUDE: %.50s", debug_msg, current->value->include.key);
/* We'll implement include rendering later */
break;
@@ -1711,8 +1714,16 @@ jsonb_get_by_path_internal(Jsonb *jb, const char *path_str, MemoryContext contex
result = MemoryContextAlloc(context, sizeof(JsonbValue));
*result = v;
/* For string values, we need to make a copy of the string data */
if (result->type == jbvString)
{
char *str_copy = palloc(result->val.string.len + 1);
memcpy(str_copy, result->val.string.val, result->val.string.len);
str_copy[result->val.string.len] = '\0';
result->val.string.val = str_copy;
}
/* Convert to a Jsonb container */
if (result->type == jbvBinary)
else if (result->type == jbvBinary)
{
tmp_val.type = jbvBinary;
tmp_val.val.binary.data = result->val.binary.data;
@@ -1843,8 +1854,16 @@ jsonb_get_by_path_internal(Jsonb *jb, const char *path_str, MemoryContext contex
result = MemoryContextAlloc(context, sizeof(JsonbValue));
*result = v;
/* For string values, we need to make a copy of the string data */
if (result->type == jbvString)
{
char *str_copy = palloc(result->val.string.len + 1);
memcpy(str_copy, result->val.string.val, result->val.string.len);
str_copy[result->val.string.len] = '\0';
result->val.string.val = str_copy;
}
/* Convert to a Jsonb container */
if (result->type == jbvBinary)
else if (result->type == jbvBinary)
{
tmp_val.type = jbvBinary;
tmp_val.val.binary.data = result->val.binary.data;

View File

@@ -1061,6 +1061,23 @@ SECTION: iterator="section", collection="page.sections"$expected40$
RAISE WARNING 'Test %: Complex nested structure with all tag types - FAILED', total_tests;
END IF;
-- Test 41: Subsequent object interpolation
total_tests := total_tests + 1;
result := test_template_parse(
$hemar$User: {{ user.profile.name }}, Age: {{ user.profile.age }}$hemar$,
$zalupa$Template parsed successfully. Structure:
TEXT: "User: "
INTERPOLATE: "user.profile.name"
TEXT: ", Age: "
INTERPOLATE: "user.profile.age"$zalupa$
);
IF result THEN
passed_tests := passed_tests + 1;
RAISE NOTICE 'Test %: Subsequent object interpolation - PASSED', total_tests;
ELSE
RAISE WARNING 'Test %: Subsequent object interpolation - FAILED', total_tests;
END IF;
-- Print summary
IF passed_tests = total_tests THEN
RAISE NOTICE '------------------------------------';