Commit db1115e2 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[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: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69575}
parent 84cf8905
......@@ -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)
......
// 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.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment