Skip to content

Commit 1f34806

Browse files
authored
jinja: coerce input for string-specific filters (#21370)
1 parent 887535c commit 1f34806

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

common/jinja/runtime.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,19 @@ value filter_expression::execute_impl(context & ctx) {
306306
filter_id = "strip"; // alias
307307
}
308308
JJ_DEBUG("Applying filter '%s' to %s", filter_id.c_str(), input->type().c_str());
309+
// TODO: Refactor filters so this coercion can be done automatically
310+
if (!input->is_undefined() && !is_val<value_string>(input) && (
311+
filter_id == "capitalize" ||
312+
filter_id == "lower" ||
313+
filter_id == "replace" ||
314+
filter_id == "strip" ||
315+
filter_id == "title" ||
316+
filter_id == "upper" ||
317+
filter_id == "wordcount"
318+
)) {
319+
JJ_DEBUG("Coercing %s to String for '%s' filter", input->type().c_str(), filter_id.c_str());
320+
input = mk_val<value_string>(input->as_string());
321+
}
309322
return try_builtin_func(ctx, filter_id, input)->invoke(func_args(ctx));
310323

311324
} else if (is_stmt<call_expression>(filter)) {

common/jinja/value.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,9 @@ const func_builtins & value_int_t::get_builtins() const {
465465
double val = static_cast<double>(args.get_pos(0)->as_int());
466466
return mk_val<value_float>(val);
467467
}},
468-
{"tojson", tojson},
468+
{"safe", tojson},
469469
{"string", tojson},
470+
{"tojson", tojson},
470471
};
471472
return builtins;
472473
}
@@ -485,8 +486,9 @@ const func_builtins & value_float_t::get_builtins() const {
485486
int64_t val = static_cast<int64_t>(args.get_pos(0)->as_float());
486487
return mk_val<value_int>(val);
487488
}},
488-
{"tojson", tojson},
489+
{"safe", tojson},
489490
{"string", tojson},
491+
{"tojson", tojson},
490492
};
491493
return builtins;
492494
}
@@ -771,6 +773,11 @@ const func_builtins & value_string_t::get_builtins() const {
771773

772774

773775
const func_builtins & value_bool_t::get_builtins() const {
776+
static const func_handler tostring = [](const func_args & args) -> value {
777+
args.ensure_vals<value_bool>();
778+
bool val = args.get_pos(0)->as_bool();
779+
return mk_val<value_string>(val ? "True" : "False");
780+
};
774781
static const func_builtins builtins = {
775782
{"default", default_value},
776783
{"int", [](const func_args & args) -> value {
@@ -783,11 +790,8 @@ const func_builtins & value_bool_t::get_builtins() const {
783790
bool val = args.get_pos(0)->as_bool();
784791
return mk_val<value_float>(val ? 1.0 : 0.0);
785792
}},
786-
{"string", [](const func_args & args) -> value {
787-
args.ensure_vals<value_bool>();
788-
bool val = args.get_pos(0)->as_bool();
789-
return mk_val<value_string>(val ? "True" : "False");
790-
}},
793+
{"safe", tostring},
794+
{"string", tostring},
791795
{"tojson", tojson},
792796
};
793797
return builtins;
@@ -1100,18 +1104,14 @@ const func_builtins & value_object_t::get_builtins() const {
11001104
}
11011105

11021106
const func_builtins & value_none_t::get_builtins() const {
1107+
static const func_handler tostring = [](const func_args &) -> value {
1108+
return mk_val<value_string>("None");
1109+
};
11031110
static const func_builtins builtins = {
11041111
{"default", default_value},
11051112
{"tojson", tojson},
1106-
{"string", [](const func_args &) -> value {
1107-
return mk_val<value_string>("None");
1108-
}},
1109-
{"safe", [](const func_args &) -> value {
1110-
return mk_val<value_string>("None");
1111-
}},
1112-
{"strip", [](const func_args &) -> value {
1113-
return mk_val<value_string>("None");
1114-
}},
1113+
{"string", tostring},
1114+
{"safe", tostring},
11151115
{"items", empty_value_fn<value_array>},
11161116
{"map", empty_value_fn<value_array>},
11171117
{"reject", empty_value_fn<value_array>},

tests/test-jinja.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,18 @@ static void test_filters(testing & t) {
523523
"hello"
524524
);
525525

526+
test_template(t, "upper array",
527+
"{{ items|upper }}",
528+
{{"items", json::array({"hello", "world"})}},
529+
"['HELLO', 'WORLD']"
530+
);
531+
532+
test_template(t, "upper dict",
533+
"{{ items|upper }}",
534+
{{"items", {{"hello", "world"}}}},
535+
"{'HELLO': 'WORLD'}"
536+
);
537+
526538
test_template(t, "capitalize",
527539
"{{ 'heLlo World'|capitalize }}",
528540
json::object(),

0 commit comments

Comments
 (0)