blob: 873a984e5893683c630d8755b55af2f3b2ca4a26 [file] [log] [blame]
// 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 "common/strings/obfuscator.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "common/util/bijective_map.h"
#include "common/util/logging.h"
namespace verible {
namespace {
static char Rot13(char c) {
if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
return c + 13;
else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
return c - 13;
else
return c;
}
// Non-random generator, just for the sake of testing.
static std::string RotateGenerator(absl::string_view input) {
std::string s(input);
for (auto& ch : s) ch = Rot13(ch);
return s;
}
TEST(ObfuscatorTest, Construction) {
Obfuscator ob(RotateGenerator);
EXPECT_TRUE(ob.GetTranslator().empty());
}
TEST(ObfuscatorTest, Transform) {
Obfuscator ob(RotateGenerator);
const auto& tran = ob.GetTranslator();
// repeat same string
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat");
EXPECT_EQ(str, "png");
EXPECT_EQ(tran.size(), 1);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "png");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("png")), "cat");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("Dog");
EXPECT_EQ(str, "Qbt");
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "png");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("png")), "cat");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("Dog")), "Qbt");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("Qbt")), "Dog");
}
}
TEST(ObfuscatorTest, Encode) {
Obfuscator ob(RotateGenerator);
ob.encode("cat", "sheep");
const auto& tran = ob.GetTranslator();
EXPECT_EQ(tran.size(), 1);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
// repeat same string
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat");
EXPECT_EQ(str, "sheep");
EXPECT_EQ(tran.size(), 1);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("dog");
EXPECT_EQ(str, "qbt");
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), "sheep");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("sheep")), "cat");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("dog")), "qbt");
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse("qbt")), "dog");
}
}
TEST(ObfuscatorTest, DecodeMode) {
Obfuscator ob(RotateGenerator);
EXPECT_FALSE(ob.is_decoding());
ob.set_decode_mode(true);
EXPECT_TRUE(ob.is_decoding());
ob.set_decode_mode(false);
EXPECT_FALSE(ob.is_decoding());
}
TEST(ObfuscatorTest, DecodeModeDoesNotAddEntries) {
Obfuscator ob(RotateGenerator);
ob.set_decode_mode(true);
EXPECT_TRUE(ob.is_decoding());
EXPECT_TRUE(ob.GetTranslator().empty());
EXPECT_EQ(ob("dog"), "dog"); // unrecognized id, unchanged
EXPECT_TRUE(ob.GetTranslator().empty());
// can still manually add entries
EXPECT_TRUE(ob.encode("shark", "snake"));
EXPECT_EQ(ob.GetTranslator().size(), 1);
EXPECT_EQ(ob("snake"), "shark"); // decoded
EXPECT_EQ(ob.GetTranslator().size(), 1);
EXPECT_EQ(ob("cow"), "cow");
EXPECT_EQ(ob.GetTranslator().size(), 1);
}
TEST(ObfuscatorTest, SaveMap) {
Obfuscator ob(RotateGenerator);
EXPECT_EQ(ob.save(), "");
EXPECT_EQ(ob("cat"), "png");
EXPECT_EQ(ob.save(), "cat png\n");
EXPECT_EQ(ob("zzz"), "mmm");
EXPECT_EQ(ob.save(), "cat png\nzzz mmm\n");
}
TEST(ObfuscatorTest, LoadMap) {
{
Obfuscator ob(RotateGenerator);
const auto status = ob.load("");
EXPECT_TRUE(status.ok()) << status.message();
}
{
Obfuscator ob(RotateGenerator);
const auto status = ob.load("cat dog");
EXPECT_TRUE(status.ok()) << status.message();
EXPECT_EQ(ob("cat"), "dog");
}
{
Obfuscator ob(RotateGenerator);
const auto status = ob.load("cat dog\n");
EXPECT_TRUE(status.ok()) << status.message();
EXPECT_EQ(ob("cat"), "dog");
}
{
Obfuscator ob(RotateGenerator);
const auto status = ob.load("cat\n"); // malformed line
EXPECT_FALSE(status.ok());
EXPECT_EQ(status.code(), absl::StatusCode::kInvalidArgument);
}
}
TEST(IdentifierObfuscatorTest, Transform) {
IdentifierObfuscator ob;
const auto& tran = ob.GetTranslator();
// repeat same string
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat"); // str is random
EXPECT_EQ(tran.size(), 1);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("dog"); // str is random
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("dog")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "dog");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat"); // str is random
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
}
}
TEST(IdentifierObfuscatorTest, EncodeInvalid) {
IdentifierObfuscator ob;
EXPECT_DEATH(ob.encode("cat", "sheep"), ""); // mismatch length
}
TEST(IdentifierObfuscatorTest, EncodeValidTransform) {
IdentifierObfuscator ob;
ob.encode("cat", "cow");
const auto& tran = ob.GetTranslator();
// repeat same string
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat");
EXPECT_EQ(str, "cow");
EXPECT_EQ(tran.size(), 1);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("Dog"); // str is random
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("Dog")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "Dog");
}
for (int i = 0; i < 2; ++i) {
const auto str = ob("cat");
EXPECT_EQ(str, "cow");
EXPECT_EQ(tran.size(), 2);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_forward("cat")), str);
EXPECT_EQ(*ABSL_DIE_IF_NULL(tran.find_reverse(std::string(str))), "cat");
}
}
} // namespace
} // namespace verible