[Intl] Fix Heap-use-after-free
Fix Heap-use-after-free READ 2 in Intl.Segmenter when the segments got free during the iteration We need to keep a copy of the string in the iterator instead of depending on the one referenced from the segments. Bug: chromium:1121156, v8:6891 Change-Id: I26ef5baccaa470dc1bd8cc229c737f556d27160e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2376173 Commit-Queue: Frank Tang <ftang@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#69575}
This commit is contained in:
parent
84cf890532
commit
db1115e267
@ -134,6 +134,7 @@ bitfield struct JSSegmentIteratorFlags extends uint31 {
|
||||
@generateCppClass
|
||||
extern class JSSegmentIterator extends JSObject {
|
||||
icu_break_iterator: Foreign; // Managed<icu::BreakIterator>
|
||||
unicode_string: Foreign; // Managed<icu::UnicodeString>
|
||||
flags: SmiTagged<JSSegmentIteratorFlags>;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(JSSegmentIterator)
|
||||
// Base segment iterator accessors.
|
||||
ACCESSORS(JSSegmentIterator, icu_break_iterator, Managed<icu::BreakIterator>,
|
||||
kIcuBreakIteratorOffset)
|
||||
ACCESSORS(JSSegmentIterator, unicode_string, Managed<icu::UnicodeString>,
|
||||
kUnicodeStringOffset)
|
||||
|
||||
inline void JSSegmentIterator::set_granularity(
|
||||
JSSegmenter::Granularity granularity) {
|
||||
|
@ -46,6 +46,13 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
|
||||
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
|
||||
Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
|
||||
|
||||
icu::UnicodeString* string = new icu::UnicodeString();
|
||||
break_iterator->getText().getText(*string);
|
||||
Handle<Managed<icu::UnicodeString>> unicode_string =
|
||||
Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, string);
|
||||
|
||||
break_iterator->setText(*string);
|
||||
|
||||
// Now all properties are ready, so we can allocate the result object.
|
||||
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
|
||||
DisallowHeapAllocation no_gc;
|
||||
@ -55,6 +62,7 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
|
||||
segment_iterator->set_flags(0);
|
||||
segment_iterator->set_granularity(granularity);
|
||||
segment_iterator->set_icu_break_iterator(*managed_break_iterator);
|
||||
segment_iterator->set_unicode_string(*unicode_string);
|
||||
|
||||
return segment_iterator;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ class JSSegmentIterator
|
||||
|
||||
// SegmentIterator accessors.
|
||||
DECL_ACCESSORS(icu_break_iterator, Managed<icu::BreakIterator>)
|
||||
DECL_ACCESSORS(unicode_string, Managed<icu::UnicodeString>)
|
||||
|
||||
DECL_PRINTER(JSSegmentIterator)
|
||||
|
||||
|
11
test/intl/regress-1121156.js
Normal file
11
test/intl/regress-1121156.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony-intl-segmenter --expose-gc
|
||||
|
||||
let segmenter = new Intl.Segmenter();
|
||||
let segments = segmenter.segment(undefined);
|
||||
for (let seg of segments) {
|
||||
segments = gc(); // free segments and call gc.
|
||||
}
|
Loading…
Reference in New Issue
Block a user