diff --git a/verifier/tests/BUILD.gn b/verifier/tests/BUILD.gn index 2c35da9c08df88bef6793dc5548ec928caddd938..c1b5fbd5716618ccc4b05347b8b4421849e3b213 100755 --- a/verifier/tests/BUILD.gn +++ b/verifier/tests/BUILD.gn @@ -30,14 +30,7 @@ verifier_test_deps = [ verifier_test_js_files = [ "test_checksum", - "test_checksum_bit", - "test_constant_pool1", - "test_constant_pool2", - "test_constant_pool3", - "test_constant_pool4", - "test_constant_pool5", - "test_constant_pool6", - "test_constant_pool7", + "test_constant_pool", ] test_js_path = "//arkcompiler/runtime_core/verifier/tests/js/" @@ -59,6 +52,7 @@ host_unittest_action("VerifierTest") { module_out_path = module_output_path sources = [ + "utils.cpp", "verify_checksum_test.cpp", "verify_constant_pool_tests.cpp", ] diff --git a/verifier/tests/js/test_checksum.js b/verifier/tests/js/test_checksum.js index 3da23a49b5766915f53e49c73b28f0e19a2234f1..8c1b3f7c06acc6b0d8d88aef3b8a0bdb043c57eb 100755 --- a/verifier/tests/js/test_checksum.js +++ b/verifier/tests/js/test_checksum.js @@ -13,23 +13,17 @@ limitations under the License. */ - -try { - a = 1; -} catch (e) { - a; +let val = 'hello'; +function setValue() { + let value = val; + return value; } -function foo(x) { - return x == undefined ? 0 : 1; +class Student { + constructor(name, age) { + this.name = name; + this.age = age; + } } -function func2(a) { - var a = 1; - if (a) { - return a; - } - else { - a += 1; - } -} \ No newline at end of file +let arr = [1, 2, 9, 0]; \ No newline at end of file diff --git a/verifier/tests/js/test_checksum_bit.js b/verifier/tests/js/test_checksum_bit.js deleted file mode 100755 index a979dec44ad712aaf74b8a143a85193603cdc260..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_checksum_bit.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - - -try { - a = 111; -} catch (e) { - a; -} - -function foo(x) { - return x == undefined ? 0 : 1; -} - -function func2(a) { - var a = 123; - if (a) { - return a; - } - else { - a += 134; - } -} \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool4.js b/verifier/tests/js/test_constant_pool.js similarity index 97% rename from verifier/tests/js/test_constant_pool4.js rename to verifier/tests/js/test_constant_pool.js index 0b0106189f95364b24422e04aa72bd9537a5c1e1..9b0e5f2a972c10f4edc3026b3bd7bf8f83edff8c 100644 --- a/verifier/tests/js/test_constant_pool4.js +++ b/verifier/tests/js/test_constant_pool.js @@ -14,7 +14,7 @@ */ let a = aaa; -function A() { +function setValue() { let b = a; return b; } diff --git a/verifier/tests/js/test_constant_pool1.js b/verifier/tests/js/test_constant_pool1.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool1.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool2.js b/verifier/tests/js/test_constant_pool2.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool2.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool3.js b/verifier/tests/js/test_constant_pool3.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool3.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool5.js b/verifier/tests/js/test_constant_pool5.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool5.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool6.js b/verifier/tests/js/test_constant_pool6.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool6.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/js/test_constant_pool7.js b/verifier/tests/js/test_constant_pool7.js deleted file mode 100644 index 0b0106189f95364b24422e04aa72bd9537a5c1e1..0000000000000000000000000000000000000000 --- a/verifier/tests/js/test_constant_pool7.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - Copyright (c) 2023 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. - */ - -let a = aaa; -function A() { - let b = a; - return b; -} - -class Student { - constructor(name, age) { - this.name = name; - this.age = age; - } -} - -let stu = new Student('zhangsan', 12); -console.log(stu.age); - -let arr = [1, 2, 3]; -console.log(arr); - -let o = { - color: 'red' -}; -console.log(o); \ No newline at end of file diff --git a/verifier/tests/utils.cpp b/verifier/tests/utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0c03bf5b8d53bfa3a1d2e91f72a09152d7a4dece --- /dev/null +++ b/verifier/tests/utils.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 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. + */ + +#include "utils.h" +#include +#include "utils/logger.h" + +namespace panda::verifier { + +void GenerateModifiedAbc(const std::vector &buffer, const std::string &filename) +{ + std::ofstream abc_file(filename, std::ios::out | std::ios::binary); + if (abc_file.fail()) { + LOG(ERROR, VERIFIER) << "Failed to open file " << filename; + return; + } + + abc_file.write(reinterpret_cast(buffer.data()), buffer.size()); + abc_file.close(); +} + +} // namespace panda::verifier \ No newline at end of file diff --git a/verifier/tests/utils.h b/verifier/tests/utils.h new file mode 100644 index 0000000000000000000000000000000000000000..420c38c4b5a6d586269d543a4a45034e0de870c9 --- /dev/null +++ b/verifier/tests/utils.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef UTILS_H +#define UTILS_H + +#include +#include + +namespace panda::verifier { + void GenerateModifiedAbc(const std::vector &buffer, const std::string &filename); +} // namespace panda::verifier + +#endif diff --git a/verifier/tests/verify_checksum_test.cpp b/verifier/tests/verify_checksum_test.cpp index 004b4c9ea47f5252908d043a38fde309d2ac5336..b685db1cf4ad07db580fe859da0dea13df0fb1bc 100644 --- a/verifier/tests/verify_checksum_test.cpp +++ b/verifier/tests/verify_checksum_test.cpp @@ -20,9 +20,10 @@ #include #include "file.h" -#include "utils/logger.h" +#include "utils.h" using namespace testing::ext; + namespace panda::verifier { class VerifierTest : public testing::Test { public: @@ -30,11 +31,15 @@ public: static void TearDownTestCase(void) {}; void SetUp() {}; void TearDown() {}; - static constexpr uint32_t MAGIC_LEN = 8U; - static constexpr uint32_t ABCFILE_OFFSET = 12U; }; -HWTEST_F(VerifierTest, verifier_test_001, TestSize.Level1) +/** +* @tc.name: verifier_checksum_001 +* @tc.desc: Verify the abc file checksum value function. +* @tc.type: FUNC +* @tc.require: file path and name +*/ +HWTEST_F(VerifierTest, verifier_checksum_001, TestSize.Level1) { const std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; panda::verifier::Verifier ver {file_name}; @@ -42,74 +47,73 @@ HWTEST_F(VerifierTest, verifier_test_001, TestSize.Level1) } /** -* @tc.name: verifier_test_001 +* @tc.name: verifier_checksum_002 * @tc.desc: Verify the modified abc file checksum value function. * @tc.type: FUNC * @tc.require: file path and name */ -HWTEST_F(VerifierTest, verifier_test_002, TestSize.Level1) +HWTEST_F(VerifierTest, verifier_checksum_002, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyChecksum()); } - std::vector bytes = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11}; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ", open failed"; - } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, ABCFILE_OFFSET, SEEK_CUR); + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); - auto size = fwrite(bytes.data(), sizeof(decltype(bytes.back())), bytes.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == bytes.size()); + std::vector buffer(std::istreambuf_iterator(base_file), {}); + + std::vector new_checksum = {0x01, 0x01, 0x01, 0x01}; + + // The 8~11 elements in the buffer of the abc file hold the checksum + buffer[8] = new_checksum[0]; + buffer[9] = new_checksum[1]; + buffer[10] = new_checksum[2]; + buffer[11] = new_checksum[3]; + + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_checksum_002.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.VerifyChecksum()); } } - /** -* @tc.name: verifier_test_003 -* @tc.desc: Verify the modified checksum bitwidth abc file checksum value function. +* @tc.name: verifier_checksum_003 +* @tc.desc: Verify the modified abc file content function. * @tc.type: FUNC * @tc.require: file path and name */ -HWTEST_F(VerifierTest, verifier_test_003, TestSize.Level1) +HWTEST_F(VerifierTest, verifier_checksum_003, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum_bit.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyChecksum()); } - std::vector bytes = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); - FILE *fp = fopen(file_name.c_str(), "wbe"); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ", open failed"; - } - EXPECT_TRUE(fp != nullptr); + std::vector buffer(std::istreambuf_iterator(base_file), {}); + + std::vector new_content = {0x01, 0x01}; - fseek(fp, 0, SEEK_SET); - fseek(fp, MAGIC_LEN, SEEK_CUR); + // The checksum calculation starts with the 12th element + buffer[12] = new_content[0]; + buffer[13] = new_content[1]; - auto size = fwrite(bytes.data(), sizeof(decltype(bytes.back())), bytes.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == bytes.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_checksum_003.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.VerifyChecksum()); } } -}; +}; // namespace panda::verifier diff --git a/verifier/tests/verify_constant_pool_tests.cpp b/verifier/tests/verify_constant_pool_tests.cpp index 3851f879c3a68f0cb6445d95be051a8fc6bb2e9d..5f5391e27251fd84e3cc65e7797334d848a1a0b6 100644 --- a/verifier/tests/verify_constant_pool_tests.cpp +++ b/verifier/tests/verify_constant_pool_tests.cpp @@ -15,14 +15,15 @@ #include "verifier.h" +#include #include #include -#include #include "file.h" -#include "utils/logger.h" +#include "utils.h" using namespace testing::ext; + namespace panda::verifier { class VerifierConstantPool : public testing::Test { public: @@ -40,7 +41,7 @@ public: */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_001, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool1.abc"; + const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; panda::verifier::Verifier ver {file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); @@ -54,35 +55,33 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_001, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_002, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool2.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector string_id = {0x0c, 0x00}; - - uint32_t code_id = 0x02f0; // the code id which contains method id in abc file - - // For format in this instruction, the method id needs to be offset by one byte - long int method_id = static_cast(code_id) + 1; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << "Failed to open file " << file_name; - } - EXPECT_TRUE(fp != nullptr); + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); - fseek(fp, 0, SEEK_SET); - fseek(fp, method_id, SEEK_CUR); + std::vector new_method_id = {0xff, 0xff}; + std::vector method_id = {0x0e, 0x00}; // The known method id in the abc file + + for (size_t i = buffer.size() - 1; i >= 0; --i) { + if (buffer[i] == method_id[0] && buffer[i + 1] == method_id[1]) { + buffer[i] = static_cast(new_method_id[0]); + buffer[i + 1] = static_cast(new_method_id[1]); + break; + } + } - auto size = fwrite(string_id.data(), sizeof(decltype(string_id.back())), string_id.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == string_id.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_002.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.VerifyConstantPool()); } } @@ -95,34 +94,35 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_002, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_003, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool3.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector string_id = {0x00, 0x01}; - - uint32_t code_id = 0x0306; // the code id which contains literal id in abc file - - // For format in this instruction, the literal id needs to be offset by three byte - long int literal_id = static_cast(code_id) + 3; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ",open fail"; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); + + std::vector new_literal_id = {0xac, 0xfc}; + std::vector literal_id = {0x0f, 0x00}; // The known literal id in the abc file + + for (size_t i = 0; i < buffer.size(); ++i) { + if (buffer[i] == literal_id[0] && buffer[i + 1] == literal_id[1]) { + buffer[i] = static_cast(new_literal_id[0]); + buffer[i + 1] = static_cast(new_literal_id[1]); + break; + } } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, literal_id, SEEK_CUR); - auto size = fwrite(string_id.data(), sizeof(decltype(string_id.back())), string_id.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == string_id.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_003.abc"; + + GenerateModifiedAbc(buffer, target_file_name); + + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.VerifyConstantPool()); } } @@ -135,34 +135,33 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_003, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_004, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool4.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector new_string_id = {0x00, 0x01}; - - uint32_t code_id = 0x0322; // the code id which contains string id in abc file - - // For format in this instruction, the literal id needs to be offset by three byte - long int string_id = static_cast(code_id) + 3; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ",open fail"; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); + + std::vector new_string_id = {0xff, 0x00}; + std::vector string_id = {0x0c, 0x00}; // The known string id in the abc file + + for (size_t i = 0; i < buffer.size(); ++i) { + if (buffer[i] == string_id[0] && buffer[i + 1] == string_id[1]) { + buffer[i] = static_cast(new_string_id[0]); + buffer[i + 1] = static_cast(new_string_id[1]); + break; + } } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, string_id, SEEK_CUR); - auto size = fwrite(new_string_id.data(), sizeof(decltype(new_string_id.back())), new_string_id.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == new_string_id.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_004.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.VerifyConstantPool()); } } @@ -175,31 +174,28 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_004, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_005, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool5.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector method_content = {0x00, 0x02}; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); - uint32_t method_id = 0x000d; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ",open fail"; - } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, method_id, SEEK_CUR); + std::vector method_content = {0x02}; + + uint32_t method_id = 0x000e; // The known method id in the abc file + + buffer[method_id] = static_cast(method_content[0]); - auto size = fwrite(method_content.data(), sizeof(decltype(method_content.back())), method_content.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == method_content.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_005.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.Verify()); } } @@ -212,31 +208,28 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_005, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_006, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool6.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector literal_content = {0x00, 0x00}; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); - uint32_t literal_id = 0x000f; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ",open fail"; - } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, literal_id, SEEK_CUR); + std::vector literal_content = {0xcf}; + + uint32_t literal_id = 0x28b; // The known literal id in the abc file + + buffer[literal_id] = static_cast(literal_content[0]); - auto size = fwrite(literal_content.data(), sizeof(decltype(literal_content.back())), literal_content.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == literal_content.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_006.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.Verify()); } } @@ -249,33 +242,30 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_006, TestSize.Level1) */ HWTEST_F(VerifierConstantPool, verifier_constant_pool_007, TestSize.Level1) { - const std::string file_name = GRAPH_TEST_ABC_DIR "test_constant_pool7.abc"; + const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool.abc"; { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {base_file_name}; EXPECT_TRUE(ver.VerifyConstantPool()); } - std::vector string_content = {'a', 'b'}; + std::ifstream base_file(base_file_name, std::ios::binary); + EXPECT_TRUE(base_file.is_open()); + + std::vector buffer(std::istreambuf_iterator(base_file), {}); - uint32_t string_id = 0x0c00; - - constexpr char const *mode = "wbe"; - FILE *fp = fopen(file_name.c_str(), mode); - if (fp == nullptr) { - LOG(ERROR, VERIFIER) << file_name << ",open fail"; - } - EXPECT_TRUE(fp != nullptr); - fseek(fp, 0, SEEK_SET); - fseek(fp, string_id, SEEK_CUR); + std::vector string_content = {0x4a}; + + uint32_t string_id = 0x000c; // The known string id in the abc file + + buffer[string_id] = static_cast(string_content[0]); - auto size = fwrite(string_content.data(), sizeof(decltype(string_content.back())), string_content.size(), fp); - fclose(fp); - fp = nullptr; - EXPECT_TRUE(size == string_content.size()); + const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_007.abc"; + GenerateModifiedAbc(buffer, target_file_name); + base_file.close(); { - panda::verifier::Verifier ver {file_name}; + panda::verifier::Verifier ver {target_file_name}; EXPECT_FALSE(ver.Verify()); } } -}; +}; // namespace panda::verifier diff --git a/verifier/verifier.cpp b/verifier/verifier.cpp index 8afa9ce3bc7e617efbe0bf76a5b62f9ae2326cdf..2c70c4dad52eda6d3d723f7d2aba269758f8352a 100644 --- a/verifier/verifier.cpp +++ b/verifier/verifier.cpp @@ -90,6 +90,7 @@ void Verifier::GetLiteralIds() bool Verifier::CheckConstantPool() { + bool check_res = true; const auto class_idx = file_->GetClasses(); for (size_t i = 0; i < class_idx.size(); i++) { uint32_t class_id = class_idx[i]; @@ -102,9 +103,12 @@ bool Verifier::CheckConstantPool() if (!file_->IsExternal(record_id)) { panda_file::ClassDataAccessor class_accessor {*file_, record_id}; class_accessor.EnumerateMethods([&](panda_file::MethodDataAccessor &method_accessor) -> void { - CheckConstantPoolInfo(method_accessor.GetMethodId()); + check_res &= CheckConstantPoolInfo(method_accessor.GetMethodId()); }); } + if (!check_res) { + return false; + } } return true; } @@ -121,9 +125,10 @@ bool Verifier::VerifyMethodId(const BytecodeInstruction &bc_ins, const panda_fil return true; } -bool Verifier::VerifyLiteralId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id) +bool Verifier::VerifyLiteralId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id, + size_t idx /* = 0 */) { - const auto arg_literal_idx = bc_ins.GetId().AsIndex(); + const auto arg_literal_idx = bc_ins.GetId(idx).AsIndex(); const auto arg_literal_id = file_->ResolveMethodIndex(method_id, arg_literal_idx); const auto literal_id = panda_file::File::EntityId(arg_literal_id).GetOffset(); auto iter = std::find(literal_ids_.begin(), literal_ids_.end(), literal_id); @@ -164,16 +169,23 @@ bool Verifier::CheckConstantPoolInfo(const panda_file::File::EntityId &method_id const auto bc_ins_last = bc_ins.JumpTo(ins_sz); while (bc_ins.GetAddress() < bc_ins_last.GetAddress()) { - // fix the scenario when instruction has more than one id, such as defefineclasswithbuffer - if (bc_ins.HasFlag(BytecodeInstruction::Flags::METHOD_ID)) { - if (!VerifyMethodId(bc_ins, method_id)) { + if (bc_ins.HasFlag(BytecodeInstruction::Flags::LITERALARRAY_ID)) { + // the idx of any instruction with a literal id is 0 except defineclasswithbuffer + size_t idx = 0; + if (bc_ins.GetOpcode() == BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8 || + bc_ins.GetOpcode() == BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8) { + idx = 1; + } + if (!VerifyLiteralId(bc_ins, method_id, idx)) { return false; } - } else if (bc_ins.HasFlag(BytecodeInstruction::Flags::LITERALARRAY_ID)) { - if (!VerifyLiteralId(bc_ins, method_id)) { + } + if (bc_ins.HasFlag(BytecodeInstruction::Flags::METHOD_ID)) { + if (!VerifyMethodId(bc_ins, method_id)) { return false; } - } else if (bc_ins.HasFlag(BytecodeInstruction::Flags::STRING_ID)) { + } + if (bc_ins.HasFlag(BytecodeInstruction::Flags::STRING_ID)) { if (!VerifyStringId(bc_ins, method_id)) { return false; } diff --git a/verifier/verifier.h b/verifier/verifier.h index 8c3d44dcf06295b3fa431b4e8782c7ee23013508..058e07bf83ee3b81685c958f70907a1d3ee8bef8 100644 --- a/verifier/verifier.h +++ b/verifier/verifier.h @@ -36,7 +36,8 @@ private: void GetLiteralIds(); bool CheckConstantPool(); bool VerifyMethodId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id); - bool VerifyLiteralId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id); + bool VerifyLiteralId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id, + size_t idx); bool VerifyStringId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id); bool CheckConstantPoolInfo(const panda_file::File::EntityId &method_id);