| // Copyright 2017-2020 The Verible Authors. |
| // |
| // 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 "verilog/transform/obfuscate.h" |
| |
| #include <sstream> |
| |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| #include "common/strings/obfuscator.h" |
| |
| namespace verilog { |
| namespace { |
| |
| using verible::IdentifierObfuscator; |
| |
| // To make these tests deterministic, obfuscation maps are pre-populated. |
| TEST(ObfuscateVerilogCodeTest, PreloadedSubstitutions) { |
| IdentifierObfuscator ob; |
| const std::pair<std::string, std::string> subs[] = { |
| {"aaa", "AAA"}, |
| {"bbb", "BBB"}, |
| {"ccc", "CCC"}, |
| }; |
| for (const auto& sub : subs) { |
| ASSERT_TRUE(ob.encode(sub.first, sub.second)); |
| } |
| const std::pair<absl::string_view, absl::string_view> kTestCases[] = { |
| {"", ""}, // empty file |
| {"\n", "\n"}, |
| {"//comments unchanged\n", "//comments unchanged\n"}, |
| {"/*comments unchanged*/\n", "/*comments unchanged*/\n"}, |
| {"aaa bbb;\n", "AAA BBB;\n"}, |
| {"aaa bbb;\nbbb aaa;\n", "AAA BBB;\nBBB AAA;\n"}, |
| {"aaa[ccc] bbb;\n", "AAA[CCC] BBB;\n"}, |
| {"aaa bbb[ccc];\n", "AAA BBB[CCC];\n"}, |
| {"parameter int aaa = 111;\n", "parameter int AAA = 111;\n"}, |
| {"parameter int aaa = ccc;\n", "parameter int AAA = CCC;\n"}, |
| {"`aaa(bbb, ccc)\n", "`AAA(BBB, CCC)\n"}, |
| {"`aaa(`bbb(`ccc)))\n", "`AAA(`BBB(`CCC)))\n"}, |
| {"`ifdef aaa\n`elsif ccc\n`else\n`endif\n", |
| "`ifdef AAA\n`elsif CCC\n`else\n`endif\n"}, |
| {"`define ccc bbb+aaa\n", "`define CCC BBB+AAA\n"}, |
| {"`define ccc `bbb+`aaa\n", "`define CCC `BBB+`AAA\n"}, |
| {"task bbb;\n $aaa;\nendtask\n", "task BBB;\n $aaa;\nendtask\n"}, |
| {"task bbb;\n $aaa();\nendtask\n", "task BBB;\n $aaa();\nendtask\n"}, |
| {"task bbb;\n $aaa($ccc());\nendtask\n", |
| "task BBB;\n $aaa($ccc());\nendtask\n"}, |
| {"function aaa()\nreturn bbb^ccc;\nendfunction\n", |
| "function AAA()\nreturn BBB^CCC;\nendfunction\n"}, |
| {"function aaa()\nreturn bbb(ccc);\nendfunction\n", |
| "function AAA()\nreturn BBB(CCC);\nendfunction\n"}, |
| {"function aaa()\nreturn {bbb,ccc};\nendfunction\n", |
| "function AAA()\nreturn {BBB,CCC};\nendfunction\n"}, |
| // token concatenation |
| {"aaa``bbb;\n", "AAA``BBB;\n"}, |
| {"`define ccc(aaa, bbb) aaa``bbb;\n", |
| "`define CCC(AAA, BBB) AAA``BBB;\n"}, |
| {"`ccc(aaa``bbb, bbb``aaa);\n", "`CCC(AAA``BBB, BBB``AAA);\n"}, |
| // comments inside defines |
| { |
| "`define ccc \\\n" |
| " // comment1 \\\n" |
| " // comment2\n", |
| "`define CCC \\\n" |
| " // comment1 \\\n" |
| " // comment2\n", |
| }, |
| { |
| "`define ccc \\\n" |
| " aaa(); \\\n" |
| " // comment1 \\\n" |
| " bbb(); \\\n" |
| " // comment2\n", |
| "`define CCC \\\n" |
| " AAA(); \\\n" |
| " // comment1 \\\n" |
| " BBB(); \\\n" |
| " // comment2\n", |
| }, |
| }; |
| for (const auto& test : kTestCases) { |
| std::ostringstream output; |
| const auto status = ObfuscateVerilogCode(test.first, &output, &ob); |
| EXPECT_TRUE(status.ok()) << "Unexpected error: " << status.message(); |
| EXPECT_EQ(output.str(), test.second); |
| } |
| } |
| |
| TEST(ObfuscateVerilogCodeTest, InputLexicalError) { |
| const absl::string_view kTestCases[] = { |
| "789badid", |
| "`FOO(8911badid)\n", |
| "`define FOO 911badid\n", |
| "`FOO(`)\n", |
| }; |
| for (const auto& test : kTestCases) { |
| IdentifierObfuscator ob; |
| std::ostringstream output; |
| const auto status = ObfuscateVerilogCode(test, &output, &ob); |
| EXPECT_FALSE(status.ok()); |
| EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument) |
| << "message: " << status.message(); |
| } |
| } |
| |
| } // namespace |
| } // namespace verilog |