Browse Source

Fix pointer handling in String replace()

pull/2358/head
Sami Vaarala 4 years ago
parent
commit
f920552788
  1. 1
      releases/releases.yaml
  2. 7
      src-input/duk_bi_string.c
  3. 17
      tests/ecmascript/test-bi-string-proto-replace-empty.js
  4. 22
      tests/ecmascript/test-bug-string-replace-ptr-handling-1.js

1
releases/releases.yaml

@ -1373,4 +1373,5 @@ duktape_releases:
- "Fix coroutine yield() dangling pointer when the yielding coroutine is no longer reachable except via the resume/yield relationship (GH-2204, GH-2332)"
- "Fix potentially unbounded recursion in CBOR encode/decode by adding duk_native_stack_check() and depth limits to recursion paths (GH-2327, GH-2340)"
- "Fix potentially unbounded recursion and assertion failure in JSON.parse() reviver walk by adding duk_native_stack_check() and depth limits (GH-2338, GH-2341)"
- "Fix pointer handling bug in String.prototype.replace() which could be triggered when search string was longer than the input string (GH-2358)"
- "Compile warning fixes (GH-2349)"

7
src-input/duk_bi_string.c

@ -664,6 +664,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
#endif /* DUK_USE_REGEXP_SUPPORT */
const duk_uint8_t *p_start, *p_end, *p; /* input string scan */
const duk_uint8_t *q_start; /* match string */
duk_size_t p_blen;
duk_size_t q_blen;
#if defined(DUK_USE_REGEXP_SUPPORT)
@ -672,13 +673,19 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {
p_start = DUK_HSTRING_GET_DATA(h_input);
p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);
p_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_input);
p = p_start;
h_search = duk_known_hstring(thr, 0);
q_start = DUK_HSTRING_GET_DATA(h_search);
q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);
if (q_blen > p_blen) {
break; /* no match */
}
p_end -= q_blen; /* ensure full memcmp() fits in while */
DUK_ASSERT(p_end >= p);
match_start_coff = 0;

17
tests/ecmascript/test-bi-string-proto-replace-empty.js

@ -0,0 +1,17 @@
// Cover empty search pattern and empty input.
/*===
foo
xfoo
fo
fxo
===*/
try {
print('foo'.replace('', ''));
print('foo'.replace('', 'x'));
print('foo'.replace('o', ''));
print('foo'.replace('o', 'x'));
} catch (e) {
print(e.stack || e);
}

22
tests/ecmascript/test-bug-string-replace-ptr-handling-1.js

@ -0,0 +1,22 @@
/*
* Reported by https://github.com/bzyo.
*/
/*===
443016350
7
done
===*/
function main() {
var v2 = "EPSILON".repeat(63288050);
print(v2.length);
var v3 = "EPSILON".replace(v2);
print(v3.length);
}
try {
main();
} catch (e) {
print(e.stack || e);
}
print('done');
Loading…
Cancel
Save