[ubsan][regexp] Avoid out-of-range casts from int to enum Result

NativeRegExpMacroAssembler::Match() can return either a Result sentinel
or an int indicating the number of matches, so it should return a plain
int which we can only safely cast to Result or IrregexpResult when it's
guaranteed to be the former case.

Bug: v8:3770
Change-Id: I4c3447e0cdebd5f825964e086574ab504a1799cd
Reviewed-on: https://chromium-review.googlesource.com/c/1435735
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59142}
This commit is contained in:
Jakob Kummerow 2019-01-24 16:42:23 -08:00 committed by Commit Bot
parent e8faf62ca0
commit cf330da43b
4 changed files with 27 additions and 35 deletions

View File

@ -444,9 +444,8 @@ int RegExpImpl::IrregexpExecRaw(Isolate* isolate, Handle<JSRegExp> regexp,
// This means that in case of failure, the output registers array is left
// untouched and contains the capture results from the previous successful
// match. We can use that to set the last match info lazily.
NativeRegExpMacroAssembler::Result res =
NativeRegExpMacroAssembler::Match(code, subject, output, output_size,
index, isolate);
int res = NativeRegExpMacroAssembler::Match(code, subject, output,
output_size, index, isolate);
if (res != NativeRegExpMacroAssembler::RETRY) {
DCHECK(res != NativeRegExpMacroAssembler::EXCEPTION ||
isolate->has_pending_exception());
@ -456,7 +455,7 @@ int RegExpImpl::IrregexpExecRaw(Isolate* isolate, Handle<JSRegExp> regexp,
RE_FAILURE);
STATIC_ASSERT(static_cast<int>(NativeRegExpMacroAssembler::EXCEPTION) ==
RE_EXCEPTION);
return static_cast<IrregexpResult>(res);
return res;
}
// If result is RETRY, the string has changed representation, and we
// must restart from scratch.

View File

@ -207,14 +207,12 @@ int NativeRegExpMacroAssembler::CheckStackGuardState(
return return_value;
}
NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
Handle<Code> regexp_code,
Handle<String> subject,
int* offsets_vector,
int offsets_vector_length,
int previous_index,
Isolate* isolate) {
// Returns a {Result} sentinel, or the number of successful matches.
int NativeRegExpMacroAssembler::Match(Handle<Code> regexp_code,
Handle<String> subject,
int* offsets_vector,
int offsets_vector_length,
int previous_index, Isolate* isolate) {
DCHECK(subject->IsFlat());
DCHECK_LE(0, previous_index);
DCHECK_LE(previous_index, subject->length());
@ -253,18 +251,12 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
StringCharacterPosition(subject_ptr, start_offset + slice_offset, no_gc);
int byte_length = char_length << char_size_shift;
const byte* input_end = input_start + byte_length;
Result res = Execute(*regexp_code,
*subject,
start_offset,
input_start,
input_end,
offsets_vector,
offsets_vector_length,
isolate);
return res;
return Execute(*regexp_code, *subject, start_offset, input_start, input_end,
offsets_vector, offsets_vector_length, isolate);
}
NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
// Returns a {Result} sentinel, or the number of successful matches.
int NativeRegExpMacroAssembler::Execute(
Code code,
String input, // This needs to be the unpacked (sliced, cons) string.
int start_offset, const byte* input_start, const byte* input_end,
@ -293,7 +285,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
AllowHeapAllocation allow_allocation;
isolate->StackOverflow();
}
return static_cast<Result>(result);
return result;
}
// clang-format off

View File

@ -212,12 +212,10 @@ class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
~NativeRegExpMacroAssembler() override;
bool CanReadUnaligned() override;
static Result Match(Handle<Code> regexp,
Handle<String> subject,
int* offsets_vector,
int offsets_vector_length,
int previous_index,
Isolate* isolate);
// Returns a {Result} sentinel, or the number of successful matches.
static int Match(Handle<Code> regexp, Handle<String> subject,
int* offsets_vector, int offsets_vector_length,
int previous_index, Isolate* isolate);
// Called from RegExp if the backtrack stack limit is hit.
// Tries to expand the stack. Returns the new stack-pointer if
@ -245,9 +243,10 @@ class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
return reinterpret_cast<Address>(&word_character_map[0]);
}
static Result Execute(Code code, String input, int start_offset,
const byte* input_start, const byte* input_end,
int* output, int output_size, Isolate* isolate);
// Returns a {Result} sentinel, or the number of successful matches.
static int Execute(Code code, String input, int start_offset,
const byte* input_start, const byte* input_end,
int* output, int output_size, Isolate* isolate);
};
} // namespace internal

View File

@ -771,9 +771,11 @@ static ArchRegExpMacroAssembler::Result Execute(Code code, String input,
Address input_start,
Address input_end,
int* captures) {
return NativeRegExpMacroAssembler::Execute(
code, input, start_offset, reinterpret_cast<byte*>(input_start),
reinterpret_cast<byte*>(input_end), captures, 0, CcTest::i_isolate());
return static_cast<NativeRegExpMacroAssembler::Result>(
NativeRegExpMacroAssembler::Execute(code, input, start_offset,
reinterpret_cast<byte*>(input_start),
reinterpret_cast<byte*>(input_end),
captures, 0, CcTest::i_isolate()));
}
TEST(MacroAssemblerNativeSuccess) {