| // 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 "common/strings/obfuscator.h" | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| namespace verilog { | |
| namespace { | |
| using verible::IdentifierObfuscator; | |
| static std::string ExpectNeverToBeCalled(absl::string_view) { | |
| ADD_FAILURE() << "This identifier generator should've never been called"; | |
| return ""; | |
| } | |
| // To make these tests deterministic, obfuscation maps are pre-populated. | |
| TEST(ObfuscateVerilogCodeTest, PreloadedSubstitutions) { | |
| IdentifierObfuscator ob(ExpectNeverToBeCalled); | |
| 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(RandomEqualLengthSymbolIdentifier); | |
| 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 |