diff --git a/BUILD.gn b/BUILD.gn index 2f7647a0db..0a79626ff3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -52,6 +52,7 @@ group("ark_host_linux_tools_packages") { "$ark_root/libpandabase:libarkbase(${host_toolchain})", "$ark_root/libpandafile:libarkfile(${host_toolchain})", "$ark_root/libziparchive:libarkziparchive(${host_toolchain})", + "$ark_root/verifier:ark_verifier(${host_toolchain})", ] } foreach(plugin, enabled_plugins) { @@ -314,6 +315,7 @@ if (!ark_standalone_build) { "$ark_root/libpandafile/tests:host_unittest", "$ark_root/libziparchive/tests:host_unittest", "$ark_root/platforms/tests:host_unittest", + "$ark_root/verifier/tests:host_unittest", ] } diff --git a/verifier/BUILD.gn b/verifier/BUILD.gn index 65e7dc0f54..65b39beb34 100644 --- a/verifier/BUILD.gn +++ b/verifier/BUILD.gn @@ -14,22 +14,21 @@ import("//arkcompiler/runtime_core/ark_config.gni") arkverifier_sources = [ + "main.cpp", "verifier.cpp", "verify.cpp", - "verify.h", -] - -arkverifier_configs = [ - "$ark_root:ark_config", - "$ark_root/libpandabase:arkbase_public_config", - "$ark_root/libpandafile:arkfile_public_config", - ":arkverifier_public_config", ] config("arkverifier_public_config") { include_dirs = [ "$ark_root/verifier" ] } +arkverifier_configs = [ + "$ark_root:ark_config", + "$ark_root/libpandafile:arkfile_public_config", + ":arkverifier_public_config", +] + ohos_executable("ark_verifier") { sources = arkverifier_sources @@ -44,8 +43,13 @@ ohos_executable("ark_verifier") { subsystem_name = "arkcompiler" } +libarkverifier_sources = [ + "verifier.cpp", + "verify.cpp", +] + ohos_shared_library("libarkverifier") { - sources = arkverifier_sources + sources = libarkverifier_sources deps = [ "$ark_root/libpandafile:libarkfile_static" ] diff --git a/verifier/main.cpp b/verifier/main.cpp new file mode 100644 index 0000000000..97b17c48be --- /dev/null +++ b/verifier/main.cpp @@ -0,0 +1,58 @@ +/* + * 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 "verify.h" + +#include "utils/pandargs.h" + +void PrintHelp(panda::PandArgParser &pa_parser) +{ + std::cerr << "Usage:" << std::endl; + std::cerr << "ark_verifier [options] input_file" << std::endl; + std::cerr << "Supported options:" << std::endl; + std::cerr << pa_parser.GetHelpString() << std::endl; +} + +bool PorcessArgs(panda::PandArgParser &pa_parser, const panda::PandArg &input_file, int argc, + const char **argv) +{ + if (!pa_parser.Parse(argc, argv)) { + PrintHelp(pa_parser); + return false; + } + + if (input_file.GetValue().empty()) { + PrintHelp(pa_parser); + return false; + } + + return true; +} + +int main(int argc, const char **argv) +{ + panda::PandArg help("help", false, "Print this message and exit"); + panda::PandArg input_file("input_file", "", "Path to the abc file"); + + panda::PandArgParser pa_parser; + pa_parser.Add(&help); + pa_parser.Add(&input_file); + + if (!PorcessArgs(pa_parser, input_file, argc, argv)) { + return 1; + } + + return Verify(input_file.GetValue()) ? 0 : 1; +} \ No newline at end of file diff --git a/verifier/tests/BUILD.gn b/verifier/tests/BUILD.gn new file mode 100755 index 0000000000..94c753ed39 --- /dev/null +++ b/verifier/tests/BUILD.gn @@ -0,0 +1,71 @@ +# 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. + +import("//arkcompiler/ets_frontend/es2panda/es2abc_config.gni") +import("//arkcompiler/runtime_core/ark_config.gni") +import("$ark_root/tests/test_helper.gni") + +verifier_test_configs = [ + "$ark_root:ark_config", + "$ark_root/libpandabase:arkbase_public_config", + "$ark_root/libpandafile:arkfile_public_config", + sdk_libc_secshared_config, +] + +verifier_test_deps = [ + "$ark_root/libpandabase:libarkbase_static", + "$ark_root/libpandafile:libarkfile_static", + "$ark_root/verifier:libarkverifier", +] + +verifier_test_js_files = [ + "test_checksum", + "test_checksum_bit", +] + +test_js_path = "//arkcompiler/runtime_core/verifier/tests/js/" + +foreach(file, verifier_test_js_files) { + es2abc_gen_abc("gen_${file}_abc") { + test_js = "${test_js_path}${file}.js" + test_abc = "$target_out_dir/${file}.abc" + + src_js = rebase_path(test_js) + dst_file = rebase_path(test_abc) + + in_puts = [ test_js ] + out_puts = [ test_abc ] + } +} + +host_unittest_action("VerifierChecksumTest") { + module_out_path = module_output_path + + sources = [ "verifier_test.cpp" ] + + include_dirs = [ "$ark_root/verifier" ] + + configs = verifier_test_configs + + deps = verifier_test_deps + test_abc_dir = rebase_path(target_out_dir) + defines = [ "GRAPH_TEST_ABC_DIR=\"${test_abc_dir}/\"" ] + foreach(file, verifier_test_js_files) { + deps += [ ":gen_${file}_abc" ] + } +} + +group("host_unittest") { + testonly = true + deps = [ ":VerifierChecksumTestAction" ] +} diff --git a/verifier/tests/js/test_checksum.js b/verifier/tests/js/test_checksum.js new file mode 100755 index 0000000000..3da23a49b5 --- /dev/null +++ b/verifier/tests/js/test_checksum.js @@ -0,0 +1,35 @@ +/* + 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 = 1; +} catch (e) { + a; +} + +function foo(x) { + return x == undefined ? 0 : 1; +} + +function func2(a) { + var a = 1; + if (a) { + return a; + } + else { + a += 1; + } +} \ No newline at end of file diff --git a/verifier/tests/js/test_checksum_bit.js b/verifier/tests/js/test_checksum_bit.js new file mode 100755 index 0000000000..a979dec44a --- /dev/null +++ b/verifier/tests/js/test_checksum_bit.js @@ -0,0 +1,35 @@ +/* + 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/verifier_test.cpp b/verifier/tests/verifier_test.cpp new file mode 100755 index 0000000000..c102caea74 --- /dev/null +++ b/verifier/tests/verifier_test.cpp @@ -0,0 +1,105 @@ +/* + * 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 "verifier.h" + +#include +#include +#include + +#include "file.h" +#include "utils/logger.h" + +using namespace testing::ext; +namespace panda::verifier { +class VerifierTest : public testing::Test { +public: + static void SetUpTestCase(void) {}; + 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) +{ + std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; + panda::verifier::Verifier ver; + EXPECT_TRUE(ver.VerifyChecksum(file_name)); +} + +/** +* @tc.name: verifier_test_001 +* @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) +{ + std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum.abc"; + panda::verifier::Verifier ver; + EXPECT_TRUE(ver.VerifyChecksum(file_name)); + 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); + + auto size = fwrite(bytes.data(), sizeof(decltype(bytes.back())), bytes.size(), fp); + fclose(fp); + fp = nullptr; + EXPECT_TRUE(size == bytes.size()); + + EXPECT_FALSE(ver.VerifyChecksum(file_name)); +} + + +/** +* @tc.name: verifier_test_002 +* @tc.desc: Verify the modified checksum bitwidth abc file checksum value function. +* @tc.type: FUNC +* @tc.require: file path and name +*/ +HWTEST_F(VerifierTest, verifier_test_003, TestSize.Level1) +{ + std::string file_name = GRAPH_TEST_ABC_DIR "test_checksum_bit.abc"; + panda::verifier::Verifier ver; + EXPECT_TRUE(ver.VerifyChecksum(file_name)); + std::vector bytes = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + + FILE *fp = fopen(file_name.c_str(), "wbe"); + if (fp == nullptr) { + LOG(ERROR, VERIFIER) << file_name << ",open fail"; + } + EXPECT_TRUE(fp != nullptr); + + fseek(fp, 0, SEEK_SET); + fseek(fp, MAGIC_LEN, SEEK_CUR); + + auto size = fwrite(bytes.data(), sizeof(decltype(bytes.back())), bytes.size(), fp); + fclose(fp); + fp = nullptr; + EXPECT_TRUE(size == bytes.size()); + + EXPECT_FALSE(ver.VerifyChecksum(file_name)); +} + +}; diff --git a/verifier/verifier.cpp b/verifier/verifier.cpp index b7b9bf8cdf..f8d7e91765 100644 --- a/verifier/verifier.cpp +++ b/verifier/verifier.cpp @@ -15,21 +15,28 @@ #include "verifier.h" +#include "zlib.h" + #include "file.h" namespace panda::verifier { -bool Verifier::Verify(const std::string &filename_in) +bool Verifier::VerifyChecksum(const std::string &filename) { std::unique_ptr file; - auto file_to_verify = panda_file::File::Open(filename_in); + auto file_to_verify = panda_file::File::Open(filename); file.swap(file_to_verify); if (file == nullptr) { return false; } - return true; + uint32_t file_chksum = file->GetHeader()->checksum; + + uint32_t abc_offset = 12U; // the offset of file content after checksum + ASSERT(file->GetHeader()->file_size > abc_offset); + uint32_t cal_chksum = adler32(1, file->GetBase() + abc_offset, file->GetHeader()->file_size - abc_offset); + return file_chksum == cal_chksum; } -} // namespace panda::verifier \ No newline at end of file +} // namespace panda::verifier diff --git a/verifier/verifier.h b/verifier/verifier.h index bc9bcabf25..0d080ebde4 100644 --- a/verifier/verifier.h +++ b/verifier/verifier.h @@ -24,8 +24,8 @@ public: Verifier() = default; ~Verifier() = default; - bool Verify(const std::string &filename_in); + bool VerifyChecksum(const std::string &filename); }; -} // namespace name +} // namespace panda::verifier -#endif \ No newline at end of file +#endif diff --git a/verifier/verify.cpp b/verifier/verify.cpp index d4694d5b7c..ad61766c57 100644 --- a/verifier/verify.cpp +++ b/verifier/verify.cpp @@ -14,44 +14,15 @@ */ #include "verify.h" -#include "utils/pandargs.h" -void PrintHelp(panda::PandArgParser &pa_parser) -{ - std::cerr << "Usage:" << std::endl; - std::cerr << "ark_disasm [options] input_file output_file" << std::endl << std::endl; - std::cerr << "Supported options:" << std::endl << std::endl; - std::cerr << pa_parser.GetHelpString() << std::endl; -} +#include "verifier.h" -bool PorcessArgs(panda::PandArgParser &pa_parser, const panda::PandArg &input_file, int argc, - const char **argv) +bool Verify(const std::string &input_file) { - if (!pa_parser.Parse(argc, argv)) { - PrintHelp(pa_parser); - return false; + panda::verifier::Verifier vf {}; + if (vf.VerifyChecksum(input_file)) { + return true; } - if (input_file.GetValue().empty()) { - PrintHelp(pa_parser); - return false; - } - - return true; -} - -int main(int argc, const char **argv) -{ - panda::PandArg help("help", false, "Print this message and exit"); - panda::PandArg input_file("input_file", "", "Path to the abc file"); - - panda::PandArgParser pa_parser; - pa_parser.Add(&help); - pa_parser.Add(&input_file); - - if (!PorcessArgs(pa_parser, input_file, argc, argv)) { - return 1; - } - - return Verify(input_file.GetValue()) ? 0 : 1; + return false; } \ No newline at end of file diff --git a/verifier/verify.h b/verifier/verify.h index 7b2cc04950..7966a8c30f 100644 --- a/verifier/verify.h +++ b/verifier/verify.h @@ -15,18 +15,8 @@ #ifndef VERIFIER_VERIFY_H #define VERIFIER_VERIFY_H -#include "verifier.h" - #include -bool Verify([[maybe_unused]] const std::string &input_file) -{ - panda::verifier::Verifier vf {}; - if (vf.Verify(input_file)) { - return true; - } - - return false; -} +bool Verify(const std::string &input_file); #endif \ No newline at end of file