Welcome! Log In Create A New Profile

Advanced

[njs] Fixed String.prototype.replace() with replacement containing "$'", "$`".

Dmitry Volyntsev
March 08, 2023 12:10AM
details: https://hg.nginx.org/njs/rev/10127d70e941
branches:
changeset: 2068:10127d70e941
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Tue Mar 07 20:51:45 2023 -0800
description:
Fixed String.prototype.replace() with replacement containing "$'", "$`".

Previously, the resulting string was might be broken when the string to
replace and the search string were UTF-8. pos is always a character
offset, it should not be directly used as a byte size or offset.

diffstat:

src/njs_string.c | 36 ++++++++++++++++++++----------------
src/test/njs_unit_test.c | 11 +++++++++++
2 files changed, 31 insertions(+), 16 deletions(-)

diffs (82 lines):

diff -r 107c7098bd6d -r 10127d70e941 src/njs_string.c
--- a/src/njs_string.c Tue Mar 07 20:38:08 2023 -0800
+++ b/src/njs_string.c Tue Mar 07 20:51:45 2023 -0800
@@ -3476,12 +3476,14 @@ njs_string_get_substitution(njs_vm_t *vm
njs_value_t *string, int64_t pos, njs_value_t *captures, int64_t ncaptures,
njs_value_t *groups, njs_value_t *replacement, njs_value_t *retval)
{
- int64_t tail, n;
- u_char c, c2, *p, *r, *end;
- njs_str_t rep, m, str, cap;
- njs_int_t ret;
- njs_chb_t chain;
- njs_value_t name, value;
+ u_char c, c2, *p, *r, *end;
+ size_t length;
+ int64_t tail, n;
+ njs_str_t rep, str, cap;
+ njs_int_t ret;
+ njs_chb_t chain;
+ njs_value_t name, value;
+ njs_string_prop_t s, m;

njs_string_get(replacement, &rep);
p = rep.start;
@@ -3513,24 +3515,26 @@ njs_string_get_substitution(njs_vm_t *vm
break;

case '&':
- njs_string_get(matched, &m);
- njs_chb_append_str(&chain, &m);
+ (void) njs_string_prop(&m, matched);
+ njs_chb_append(&chain, m.start, m.size);
p += 2;
break;

case '`':
- njs_string_get(string, &str);
- njs_chb_append(&chain, str.start, pos);
+ (void) njs_string_prop(&s, string);
+ n = njs_string_offset(&s, pos) - s.start;
+ njs_chb_append(&chain, s.start, n);
p += 2;
break;

case '\'':
- njs_string_get(matched, &m);
- tail = pos + m.length;
-
- njs_string_get(string, &str);
- njs_chb_append(&chain, &str.start[tail],
- njs_max((int64_t) str.length - tail, 0));
+ length = njs_string_prop(&m, matched);
+ (void) njs_string_prop(&s, string);
+
+ tail = njs_string_offset(&s, pos + length) - s.start;
+
+ njs_chb_append(&chain, &s.start[tail],
+ njs_max((int64_t) s.size - tail, 0));
p += 2;
break;

diff -r 107c7098bd6d -r 10127d70e941 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Mar 07 20:38:08 2023 -0800
+++ b/src/test/njs_unit_test.c Tue Mar 07 20:51:45 2023 -0800
@@ -8887,6 +8887,17 @@ static njs_unit_test_t njs_test[] =
{ njs_str("'abcdbe'.replaceAll('b', '|$`X$\\'|')"),
njs_str("a|aXcdbe|cd|abcdXe|e") },

+ { njs_str("var r = 'αβγ'.replace('β', \"$'\"); [r, r.length]"),
+ njs_str("αγγ,3") },
+
+ { njs_str("var r = 'αβγαβγ'.replaceAll('β', \"$'\"); [r, r.length]"),
+ njs_str("αγαβγγαγγ,9") },
+
+ { njs_str("var r = 'αβγ'.replace('β', \"$`\"); [r, r.length]"),
+ njs_str("ααγ,3") },
+
+ { njs_str("var r = 'αβγαβγ'.replaceAll('β', \"$`\"); [r, r.length]"),
+ njs_str("ααγααβγαγ,9") },

{ njs_str("'ABC'.replace('B', '$<g>')"),
njs_str("A$<g>C") },
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed String.prototype.replace() with replacement containing "$'", "$`".

Dmitry Volyntsev 385 March 08, 2023 12:10AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 303
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready