[regexp] Stricter bounds checks in interpreter

This change updates the RegExp bytecode generator to emit checks for
larger eats_at_least values when they are available, so we can fail to
match earlier in some cases.

Bug: v8:9305
Change-Id: I96740531e142ff8dced41c49b774845b07df6ae6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1709768
Commit-Queue: Seth Brenith <seth.brenith@microsoft.com>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62942}
This commit is contained in:
Seth Brenith 2019-07-26 07:47:04 -07:00 committed by Commit Bot
parent 0e8215eaee
commit 5ce023df29
3 changed files with 19 additions and 3 deletions

View File

@ -176,8 +176,14 @@ void RegExpBytecodeGenerator::LoadCurrentCharacterImpl(int cp_offset,
bool check_bounds,
int characters,
int eats_at_least) {
// TODO(v8:9305): Make use of eats_at_least value to perform a bigger bounds-
// check if it doesn't match the number of preloaded characters.
DCHECK_GE(eats_at_least, characters);
if (eats_at_least > characters && check_bounds) {
DCHECK(is_uint24(cp_offset + eats_at_least));
Emit(BC_CHECK_CURRENT_POSITION, cp_offset + eats_at_least);
EmitOrLink(on_failure);
check_bounds = false; // Load below doesn't need to check.
}
DCHECK_LE(kMinCPOffset, cp_offset);
DCHECK_GE(kMaxCPOffset, cp_offset);
int bytecode;

View File

@ -67,7 +67,8 @@ const int BYTECODE_SHIFT = 8;
V(CHECK_NOT_AT_START, 48, 8) /* bc8 offset24 addr32 */ \
V(CHECK_GREEDY, 49, 8) /* bc8 pad24 addr32 */ \
V(ADVANCE_CP_AND_GOTO, 50, 8) /* bc8 offset24 addr32 */ \
V(SET_CURRENT_POSITION_FROM_END, 51, 4) /* bc8 idx24 */
V(SET_CURRENT_POSITION_FROM_END, 51, 4) /* bc8 idx24 */ \
V(CHECK_CURRENT_POSITION, 52, 8) /* bc8 idx24 addr32 */
#define DECLARE_BYTECODES(name, code, length) static const int BC_##name = code;
BYTECODE_ITERATOR(DECLARE_BYTECODES)

View File

@ -661,6 +661,15 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array,
pc += BC_SET_CURRENT_POSITION_FROM_END_LENGTH;
break;
}
BYTECODE(CHECK_CURRENT_POSITION) {
int pos = current + (insn >> BYTECODE_SHIFT);
if (pos > subject.length() || pos < 0) {
pc = code_base + Load32Aligned(pc + 4);
} else {
pc += BC_CHECK_CURRENT_POSITION_LENGTH;
}
break;
}
default:
UNREACHABLE();
break;