From: Dmitry Volyntsev Date: Wed, 8 Mar 2023 04:51:45 +0000 (-0800) Subject: Fixed String.prototype.replace() with replacement containing "$'", "$`". X-Git-Tag: 0.7.11~1 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=485b3657f288209d894389ff75285c747cecf08e;p=njs.git 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. --- diff --git a/src/njs_string.c b/src/njs_string.c index 4227a6d8..d2eb55ed 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -3476,12 +3476,14 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, 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, njs_value_t *matched, 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; + length = njs_string_prop(&m, matched); + (void) njs_string_prop(&s, string); + + tail = njs_string_offset(&s, pos + length) - s.start; - njs_string_get(string, &str); - njs_chb_append(&chain, &str.start[tail], - njs_max((int64_t) str.length - tail, 0)); + njs_chb_append(&chain, &s.start[tail], + njs_max((int64_t) s.size - tail, 0)); p += 2; break; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 3864e197..be982ec8 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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', '$')"), njs_str("A$C") },