diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-11 23:37:35 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-11 23:37:35 +0100 |
commit | fa473930f424bf17a9e545b601c84dd2e61364e3 (patch) | |
tree | 41a29cb3ad0ebaf93f6b6248e92073fe4d8788ff /js/src/irregexp/RegExpInterpreter.cpp | |
parent | b00601953bade944cd6df9cde6fcdd1f10d76feb (diff) | |
download | UXP-fa473930f424bf17a9e545b601c84dd2e61364e3.tar UXP-fa473930f424bf17a9e545b601c84dd2e61364e3.tar.gz UXP-fa473930f424bf17a9e545b601c84dd2e61364e3.tar.lz UXP-fa473930f424bf17a9e545b601c84dd2e61364e3.tar.xz UXP-fa473930f424bf17a9e545b601c84dd2e61364e3.zip |
Issue #1279 - Implement regular expression lookbehind
Based on Tom Schuster's work, with extra minters for unicode.
Diffstat (limited to 'js/src/irregexp/RegExpInterpreter.cpp')
-rw-r--r-- | js/src/irregexp/RegExpInterpreter.cpp | 74 |
1 files changed, 69 insertions, 5 deletions
diff --git a/js/src/irregexp/RegExpInterpreter.cpp b/js/src/irregexp/RegExpInterpreter.cpp index 7fd2d983a..d09b4671e 100644 --- a/js/src/irregexp/RegExpInterpreter.cpp +++ b/js/src/irregexp/RegExpInterpreter.cpp @@ -222,8 +222,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha } break; BYTECODE(LOAD_CURRENT_CHAR) { - size_t pos = current + (insn >> BYTECODE_SHIFT); - if (pos >= length) { + int pos = current + (insn >> BYTECODE_SHIFT); + if (pos >= (int)length || pos < 0) { pc = byteCode + Load32Aligned(pc + 4); } else { current_char = chars[pos]; @@ -238,8 +238,8 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha break; } BYTECODE(LOAD_2_CURRENT_CHARS) { - size_t pos = current + (insn >> BYTECODE_SHIFT); - if (pos + 2 > length) { + int pos = current + (insn >> BYTECODE_SHIFT); + if (pos + 2 > (int)length || pos < 0) { pc = byteCode + Load32Aligned(pc + 4); } else { CharT next = chars[pos + 1]; @@ -425,6 +425,30 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha pc += BC_CHECK_NOT_BACK_REF_LENGTH; break; } + BYTECODE(CHECK_NOT_BACK_REF_BACKWARD) { + int from = registers[insn >> BYTECODE_SHIFT]; + int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; + if (from < 0 || len <= 0) { + pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH; + break; + } + if (int(current) - len < 0) { + pc = byteCode + Load32Aligned(pc + 4); + break; + } else { + int i; + for (i = 0; i < len; i++) { + if (chars[from + i] != chars[int(current) - len + i]) { + pc = byteCode + Load32Aligned(pc + 4); + break; + } + } + if (i < len) break; + current -= len; + } + pc += BC_CHECK_NOT_BACK_REF_BACKWARD_LENGTH; + break; + } BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) { int from = registers[insn >> BYTECODE_SHIFT]; int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; @@ -465,6 +489,46 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha } break; } + BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD) { + int from = registers[insn >> BYTECODE_SHIFT]; + int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; + if (from < 0 || len <= 0) { + pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH; + break; + } + if (int(current) - len < 0) { + pc = byteCode + Load32Aligned(pc + 4); + break; + } + if (CaseInsensitiveCompareStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) { + current -= len; + pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH; + } else { + pc = byteCode + Load32Aligned(pc + 4); + } + break; + + } + BYTECODE(CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_UNICODE) { + int from = registers[insn >> BYTECODE_SHIFT]; + int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from; + if (from < 0 || len <= 0) { + pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH; + break; + } + if (int(current) - len < 0) { + pc = byteCode + Load32Aligned(pc + 4); + break; + } + if (CaseInsensitiveCompareUCStrings(chars + from, chars + int(current) - len, len * sizeof(CharT))) { + current -= len; + pc += BC_CHECK_NOT_BACK_REF_NO_CASE_BACKWARD_LENGTH; + } else { + pc = byteCode + Load32Aligned(pc + 4); + } + break; + + } BYTECODE(CHECK_AT_START) if (current == 0) pc = byteCode + Load32Aligned(pc + 4); @@ -472,7 +536,7 @@ irregexp::InterpretCode(JSContext* cx, const uint8_t* byteCode, const CharT* cha pc += BC_CHECK_AT_START_LENGTH; break; BYTECODE(CHECK_NOT_AT_START) - if (current == 0) + if (current + (insn >> BYTECODE_SHIFT) == 0) pc += BC_CHECK_NOT_AT_START_LENGTH; else pc = byteCode + Load32Aligned(pc + 4); |