details: https://hg.nginx.org/njs/rev/10127d70e941 branches: changeset: 2068:10127d70e941 user: Dmitry Volyntsev <xei...@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