1 // Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <stdint.h>
10 
11 #include <vector>
12 #include <string>
13 
14 #include <exceptions/exceptions.h>
15 
16 #include <util/encode/hex.h>
17 
18 #include <gtest/gtest.h>
19 
20 using namespace std;
21 using namespace isc;
22 using namespace isc::util::encode;
23 
24 namespace {
25 const string hex_txt("DEADBEEFDECADE");
26 const string hex_txt_space("DEAD BEEF DECADE");
27 const string hex_txt_lower("deadbeefdecade");
28 
29 class HexTest : public ::testing::Test {
30 protected:
HexTest()31     HexTest() : encoding_chars("0123456789ABCDEF") {}
32     vector<uint8_t> decoded_data;
33     const string encoding_chars;
34 };
35 
TEST_F(HexTest,encodeHex)36 TEST_F(HexTest, encodeHex) {
37     std::vector<uint8_t> data;
38 
39     data.push_back(0xde);
40     data.push_back(0xad);
41     data.push_back(0xbe);
42     data.push_back(0xef);
43     data.push_back(0xde);
44     data.push_back(0xca);
45     data.push_back(0xde);
46     EXPECT_EQ(hex_txt, encodeHex(data));
47 }
48 
49 void
compareData(const std::vector<uint8_t> & data)50 compareData(const std::vector<uint8_t>& data) {
51     EXPECT_EQ(0xde, data[0]);
52     EXPECT_EQ(0xad, data[1]);
53     EXPECT_EQ(0xbe, data[2]);
54     EXPECT_EQ(0xef, data[3]);
55     EXPECT_EQ(0xde, data[4]);
56     EXPECT_EQ(0xca, data[5]);
57     EXPECT_EQ(0xde, data[6]);
58 }
59 
TEST_F(HexTest,decodeHex)60 TEST_F(HexTest, decodeHex) {
61     std::vector<uint8_t> result;
62 
63     decodeHex(hex_txt, result);
64     compareData(result);
65 
66     // lower case hex digits should be accepted
67     result.clear();
68     decodeHex(hex_txt_lower, result);
69     compareData(result);
70 
71     // white space should be ignored
72     result.clear();
73     decodeHex(hex_txt_space, result);
74     compareData(result);
75 
76     // Bogus input: should fail
77     result.clear();
78     EXPECT_THROW(decodeHex("1x", result), BadValue);
79 
80     // Bogus input: encoded string must have an even number of characters.
81     result.clear();
82     EXPECT_THROW(decodeHex("dea", result), BadValue);
83 }
84 
85 // For Hex encode/decode we use handmade mappings, so it's prudent to test the
86 // entire mapping table explicitly.
TEST_F(HexTest,decodeMap)87 TEST_F(HexTest, decodeMap) {
88     string input("00");       // input placeholder
89 
90     // See Base32HexTest.decodeMap for details of the following tests.
91     for (int i = 0; i < 256; ++i) {
92         input[1] = i;
93 
94         const char ch = toupper(i);
95         const size_t pos = encoding_chars.find(ch);
96         if (pos == string::npos) {
97             EXPECT_THROW(decodeHex(input, decoded_data), BadValue);
98         } else {
99             decodeHex(input, decoded_data);
100             EXPECT_EQ(1, decoded_data.size());
101             EXPECT_EQ(pos, decoded_data[0]);
102         }
103     }
104 }
105 
TEST_F(HexTest,encodeMap)106 TEST_F(HexTest, encodeMap) {
107     for (uint8_t i = 0; i < 16; ++i) {
108         decoded_data.clear();
109         decoded_data.push_back(i);
110         EXPECT_EQ(encoding_chars[i], encodeHex(decoded_data)[1]);
111     }
112 }
113 
114 }
115