fix engine inconsistency bug

issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7BLK2

Signed-off-by: 王笑佳 <wangxiaojia5@huawei.com>
This commit is contained in:
王笑佳 2023-06-07 17:43:22 +08:00
parent 2ac1b23397
commit ec5c8ea49d
6 changed files with 155 additions and 53 deletions

View File

@ -308,35 +308,13 @@ public:
return !MatchFailed();
}
uint32_t currentChar = GetCurrentChar();
uint32_t currentCharNext = currentChar;
if (IsIgnoreCase()) {
currentChar = static_cast<uint32_t>(RegExpParser::Canonicalize(currentChar, IsUtf16()));
currentCharNext = static_cast<uint32_t>(RegExpParser::GetcurrentCharNext(currentChar));
}
uint16_t rangeCount = byteCode.GetU16(GetCurrentPC() + 1);
bool isFound = false;
int32_t idxMin = 0;
int32_t idxMax = static_cast<int32_t>(rangeCount - 1);
int32_t idx = 0;
uint32_t low = 0;
uint32_t high =
byteCode.GetU16(GetCurrentPC() + RANGE32_HEAD_OFFSET + idxMax * RANGE32_MAX_HALF_OFFSET + RANGE32_OFFSET);
if (currentChar <= high) {
while (idxMin <= idxMax) {
idx = (idxMin + idxMax) / RANGE32_OFFSET;
low = byteCode.GetU16(GetCurrentPC() + RANGE32_HEAD_OFFSET + static_cast<uint32_t>(idx) *
RANGE32_MAX_HALF_OFFSET);
high = byteCode.GetU16(GetCurrentPC() + RANGE32_HEAD_OFFSET + static_cast<uint32_t>(idx) *
RANGE32_MAX_HALF_OFFSET + RANGE32_OFFSET);
if (currentChar < low) {
idxMax = idx - 1;
} else if (currentChar > high) {
idxMin = idx + 1;
} else {
isFound = true;
break;
}
}
}
if (isFound) {
if (IsFoundOpRange(GetCurrentPC(), currentChar, byteCode, rangeCount) ||
IsFoundOpRange(GetCurrentPC(), currentCharNext, byteCode, rangeCount)) {
AdvanceOffset(rangeCount * RANGE32_MAX_HALF_OFFSET + RANGE32_HEAD_OFFSET);
} else {
if (MatchFailed()) {
@ -345,7 +323,6 @@ public:
}
return true;
}
inline bool HandleOpBackReference(const DynChunk &byteCode, uint8_t opCode)
{
uint32_t captureIndex = byteCode.GetU8(GetCurrentPC() + 1);
@ -591,6 +568,36 @@ public:
return currentPtr_ >= inputEnd_;
}
bool IsFoundOpRange(const uint32_t currentPc, const uint32_t nowChar,
const DynChunk &byteCode, const uint16_t rangeCount)
{
bool isFound = false;
int32_t idxMin = 0;
int32_t idxMax = static_cast<int32_t>(rangeCount - 1);
int32_t idx = 0;
uint32_t low = 0;
uint32_t high =
byteCode.GetU16(currentPc + RANGE32_HEAD_OFFSET + idxMax * RANGE32_MAX_HALF_OFFSET + RANGE32_OFFSET);
if (nowChar <= high) {
while (idxMin <= idxMax) {
idx = (idxMin + idxMax) / RANGE32_OFFSET;
low = byteCode.GetU16(currentPc + RANGE32_HEAD_OFFSET + static_cast<uint32_t>(idx) *
RANGE32_MAX_HALF_OFFSET);
high = byteCode.GetU16(currentPc + RANGE32_HEAD_OFFSET + static_cast<uint32_t>(idx) *
RANGE32_MAX_HALF_OFFSET + RANGE32_OFFSET);
if (nowChar < low) {
idxMax = idx - 1;
} else if (nowChar > high) {
idxMin = idx + 1;
} else {
isFound = true;
break;
}
}
}
return isFound;
}
uint32_t GetCurrentPC() const
{
return currentPc_;
@ -693,6 +700,7 @@ private:
static constexpr size_t RANGE32_OFFSET = 2;
static constexpr uint32_t STACK_MULTIPLIER = 2;
static constexpr uint32_t MIN_STACK_SIZE = 8;
static constexpr int TMP_BUF_SIZE = 128;
uint8_t *input_ = nullptr;
uint8_t *inputEnd_ = nullptr;
bool isWideChar_ = false;

View File

@ -1265,12 +1265,12 @@ bool RegExpParser::ParseClassRanges(RangeSet *result)
}
}
result->Insert(c1, c2);
if (IsIgnoreCase()) {
ProcessIntersection(result);
}
} else {
result->Insert(s1);
}
if (IsIgnoreCase()) {
ProcessIntersection(result);
}
}
Advance();
return true;
@ -1305,9 +1305,6 @@ uint32_t RegExpParser::ParseClassAtom(RangeSet *atom)
} else {
Advance();
}
if (IsIgnoreCase()) {
value = static_cast<uint32_t>(Canonicalize(value, IsUtf16()));
}
atom->Insert(RangeSet(value));
ret = value;
break;
@ -1464,4 +1461,27 @@ int RegExpParser::IsIdentFirst(uint32_t c)
return static_cast<int>(u_isIDStart(c));
}
}
} // namespace panda::ecmascript
int RegExpParser::Canonicalize(int c, bool isUnicode)
{
if (c < TMP_BUF_SIZE) { // NOLINTNEXTLINE(readability-magic-numbers)
if (c >= 'a' && c <= 'z') {
c = c - 'a' + 'A';
}
} else {
int cur = c;
if (isUnicode) {
c = u_tolower(static_cast<UChar32>(c));
if (c >= 'a' && c <= 'z') {
c = cur;
}
} else {
c = u_toupper(static_cast<UChar32>(c));
if (c >= 'A' && c <= 'Z') {
c = cur;
}
}
}
return c;
}
} // namespace panda::ecmascript

View File

@ -54,7 +54,8 @@ public:
static constexpr uint32_t UNICODE_HEX_ADVANCE = 2;
static constexpr uint32_t CAPTURE_CONUT_ADVANCE = 3;
static constexpr uint32_t UTF8_CHAR_LEN_MAX = 6;
static int Canonicalize(int c, bool isUnicode);
explicit RegExpParser(Chunk *chunk)
: base_(nullptr),
pc_(nullptr),
@ -176,25 +177,15 @@ public:
return (flags_ & FLAG_STICKY) != 0;
}
inline static int Canonicalize(int c, bool isUnicode)
inline static int GetcurrentCharNext(int c)
{
if (c < TMP_BUF_SIZE) { // NOLINTNEXTLINE(readability-magic-numbers)
if (c >= 'a' && c <= 'z') {
c = c - 'a' + 'A';
}
} else {
int cur = c;
if (isUnicode) {
c = u_tolower(static_cast<UChar32>(c));
if (c >= 'a' && c <= 'z') {
c = cur;
}
} else {
c = u_toupper(static_cast<UChar32>(c));
if (c >= 'A' && c <= 'Z') {
c = cur;
}
}
int cur = c;
c = u_tolower(static_cast<UChar32>(c));
if (c == cur) {
c = u_toupper(static_cast<UChar32>(c));
}
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
c = cur;
}
return c;
}

View File

@ -0,0 +1,18 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_moduletest_action("regexp") {
deps = []
}

View File

@ -0,0 +1,21 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
true
true
true
true
true
true
true

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* @tc.name:regexp
* @tc.desc:test Regexp
* @tc.type: FUNC
* @tc.require: issueI5NO8G
*/
var reg = /[\x5d-\x7e]/i;
var result = reg.test("a");
print(result);
// true
var reg1 = new RegExp("^[-+]?([0-9]+)?(\\٫[0-9]{1,})?$");
var result1 = reg1.test('0٫0000000000001');
print(result1);
// true
var reg2 = /^[Α-ώ]+$/i
print(reg2.test('άέήίΰϊϋόύώ'));
// true
print(reg2.test('ΆΈΉΊΪΫΎΏ'));
// true
print(reg2.test('αβγδεζηθικλμνξοπρςστυφχψω'));
// true
print(reg2.test('ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ'));
// true
let reg3 =/^[A-Z0-9_\-]*$/i
print(reg3.test(''))
//true