Skip to content

Commit c3ba036

Browse files
emanuele6owenthereal
authored andcommitted
builtins: make ltrimstr and rtrimstr error for non-string inputs
Previously, ltrimstr/rtrimstr would just let the input pass through for non-string inputs or arguments. That was happening because, they were leaking the errors returned by startswith/endswith treating them as if they were jv_false(). The leak was resolved by jqlang#2977 for 1.7.1 This patch rewrites ltrimstr and rtrimstr in jq, and makes them not ignore startswith and endswith errors anymore.
1 parent f08cac0 commit c3ba036

File tree

3 files changed

+18
-33
lines changed

3 files changed

+18
-33
lines changed

src/builtin.c

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -294,37 +294,6 @@ static jv f_endswith(jq_state *jq, jv a, jv b) {
294294
return ret;
295295
}
296296

297-
static jv f_ltrimstr(jq_state *jq, jv input, jv left) {
298-
jv startswith = f_startswith(jq, jv_copy(input), jv_copy(left));
299-
if (jv_get_kind(startswith) != JV_KIND_TRUE) {
300-
jv_free(startswith);
301-
jv_free(left);
302-
return input;
303-
}
304-
/*
305-
* FIXME It'd be better to share the suffix with the original input --
306-
* that we could do, we just can't share prefixes.
307-
*/
308-
int prefixlen = jv_string_length_bytes(left);
309-
jv res = jv_string_sized(jv_string_value(input) + prefixlen,
310-
jv_string_length_bytes(jv_copy(input)) - prefixlen);
311-
jv_free(input);
312-
return res;
313-
}
314-
315-
static jv f_rtrimstr(jq_state *jq, jv input, jv right) {
316-
jv endswith = f_endswith(jq, jv_copy(input), jv_copy(right));
317-
if (jv_get_kind(endswith) == JV_KIND_TRUE) {
318-
jv res = jv_string_sized(jv_string_value(input),
319-
jv_string_length_bytes(jv_copy(input)) - jv_string_length_bytes(right));
320-
jv_free(input);
321-
return res;
322-
}
323-
jv_free(endswith);
324-
jv_free(right);
325-
return input;
326-
}
327-
328297
jv binop_minus(jv a, jv b) {
329298
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
330299
jv r = jv_number(jv_number_value(a) - jv_number_value(b));
@@ -1736,8 +1705,6 @@ BINOPS
17361705
{f_keys_unsorted, "keys_unsorted", 1},
17371706
{f_startswith, "startswith", 2},
17381707
{f_endswith, "endswith", 2},
1739-
{f_ltrimstr, "ltrimstr", 2},
1740-
{f_rtrimstr, "rtrimstr", 2},
17411708
{f_string_split, "split", 2},
17421709
{f_string_explode, "explode", 1},
17431710
{f_string_implode, "implode", 1},

src/builtin.jq

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ def fromdateiso8601: strptime("%Y-%m-%dT%H:%M:%SZ")|mktime;
7474
def todateiso8601: strftime("%Y-%m-%dT%H:%M:%SZ");
7575
def fromdate: fromdateiso8601;
7676
def todate: todateiso8601;
77+
def ltrimstr($left): if startswith($left) then .[$left | length:] end;
78+
def rtrimstr($right): if endswith($right) then .[:$right | -length] end;
7779
def match(re; mode): _match_impl(re; mode; false)|.[];
7880
def match($val): ($val|type) as $vt | if $vt == "string" then match($val; null)
7981
elif $vt == "array" and ($val | length) > 1 then match($val[0]; $val[1])

tests/jq.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,3 +2115,19 @@ try ltrimstr("x") catch "x", try rtrimstr("x") catch "x" | "ok"
21152115
{"hey":[]}
21162116
"ok"
21172117
"ok"
2118+
2119+
# ltrimstr/1 and rtrimstr/1 return an error for non-strings. #2969
2120+
2121+
.[] as [$x, $y] | try ["ok", ($x | ltrimstr($y))] catch ["ko", .]
2122+
[["hi",1],[1,"hi"],["hi","hi"],[1,1]]
2123+
["ko","startswith() requires string inputs"]
2124+
["ko","startswith() requires string inputs"]
2125+
["ok",""]
2126+
["ko","startswith() requires string inputs"]
2127+
2128+
.[] as [$x, $y] | try ["ok", ($x | rtrimstr($y))] catch ["ko", .]
2129+
[["hi",1],[1,"hi"],["hi","hi"],[1,1]]
2130+
["ko","endswith() requires string inputs"]
2131+
["ko","endswith() requires string inputs"]
2132+
["ok",""]
2133+
["ko","endswith() requires string inputs"]

0 commit comments

Comments
 (0)