mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
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:
parent
2ac1b23397
commit
ec5c8ea49d
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
@ -54,6 +54,7 @@ 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),
|
||||
@ -176,26 +177,16 @@ 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 {
|
||||
if (c == cur) {
|
||||
c = u_toupper(static_cast<UChar32>(c));
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
}
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
||||
c = cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
inline static void ProcessIntersection(RangeSet *result)
|
||||
|
18
test/moduletest/regexp/BUILD.gn
Normal file
18
test/moduletest/regexp/BUILD.gn
Normal 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 = []
|
||||
}
|
21
test/moduletest/regexp/expect_output.txt
Normal file
21
test/moduletest/regexp/expect_output.txt
Normal 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
|
||||
|
44
test/moduletest/regexp/regexp.js
Normal file
44
test/moduletest/regexp/regexp.js
Normal 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
|
Loading…
Reference in New Issue
Block a user