Skip to content

Commit 9ceece8

Browse files
authored
Fix string position calculation in @@replace (#3831)
Fixes #3817. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
1 parent d06c3a7 commit 9ceece8

3 files changed

Lines changed: 36 additions & 1 deletion

File tree

jerry-core/ecma/operations/ecma-regexp-object.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3115,7 +3115,22 @@ ecma_regexp_replace_helper (ecma_value_t this_arg, /**< this argument */
31153115
(lit_utf8_size_t) (match_position_p - source_position_p));
31163116
replace_ctx.match_byte_pos = (lit_utf8_size_t) (match_position_p - replace_ctx.string_p);
31173117

3118-
source_position_p = JERRY_MIN (match_position_p + matched_str_size, string_end_p);
3118+
if ((string_flags & ECMA_STRING_FLAG_IS_ASCII) && matched_str_size == matched_str_length)
3119+
{
3120+
source_position_p = JERRY_MIN (match_position_p + matched_str_size, string_end_p);
3121+
}
3122+
else
3123+
{
3124+
lit_utf8_size_t code_unit_count = matched_str_length;
3125+
3126+
while (code_unit_count-- > 0 && JERRY_LIKELY (match_position_p < string_end_p))
3127+
{
3128+
lit_utf8_incr (&match_position_p);
3129+
}
3130+
3131+
source_position_p = match_position_p;
3132+
}
3133+
31193134
replace_ctx.index = JERRY_MIN (position + matched_str_length, string_length);
31203135
}
31213136

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
var replace = RegExp.prototype[Symbol.replace];
16+
replace.call({ exec : ( ) => { return { } } }, '^o𓙦һ', "a");

tests/jerry/es2015/symbol-replace.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,10 @@ try {
621621
assert (e instanceof TypeError);
622622
}
623623

624+
assert(replace.call({ exec : ( ) => { return { } } }, 'һ', "a") === "a");
625+
assert(replace.call({ exec : ( ) => { return { } } }, 'һһһһһһһһһ', "a") === "a");
626+
assert(replace.call({ exec : ( ) => { return { } } }, 'һһһһһһһһһһ', "a") === "aһ");
627+
624628
/* Object with custom @@replace method */
625629
var o = {}
626630
o[Symbol.replace] = function () {

0 commit comments

Comments
 (0)