1 /* Reverse Engineer's Hex Editor
2  * Copyright (C) 2018-2019 Daniel Collins <solemnwarning@solemnwarning.net>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published by
6  * the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc., 51
15  * Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 */
17 
18 #include "../src/platform.hpp"
19 #include <gtest/gtest.h>
20 
21 #include "../src/util.hpp"
22 
23 #define PARSE_ASCII_NIBBLE_OK(c, expect) \
24 { \
25 	EXPECT_NO_THROW({ \
26 		unsigned char r = REHex::parse_ascii_nibble(c); \
27 		EXPECT_EQ(r, expect) << "REHex::parse_ascii_nibble("  << c << ") returns correct value"; \
28 	}) << "REHex::parse_ascii_nibble(" << c << ") doesn't throw"; \
29 }
30 
31 #define PARSE_ASCII_NIBBLE_BAD(c) \
32 	EXPECT_THROW(REHex::parse_ascii_nibble((char)c), REHex::ParseError) << "REHex::parse_ascii_nibble(" << c << ") throws ParseError";
33 
34 #define PARSE_HEX_STRING_OK(hex, ...) \
35 { \
36 	std::vector<unsigned char> expect_data( { __VA_ARGS__ } ); \
37 	\
38 	EXPECT_NO_THROW({ \
39 		std::vector<unsigned char> got_data = REHex::parse_hex_string(hex); \
40 		EXPECT_EQ(got_data, expect_data) << "REHex::parse_hex_string(" #hex ") returns correct data"; \
41 	}) << "REHex::parse_hex_string(" << #hex << ") doesn't throw"; \
42 }
43 
44 #define PARSE_HEX_STRING_BAD(hex) \
45 	EXPECT_THROW(REHex::parse_hex_string(hex), REHex::ParseError) << "REHex::parse_hex_string(" #hex ") throws ParseError";
46 
47 using namespace REHex;
48 
TEST(Util,parse_ascii_nibble)49 TEST(Util, parse_ascii_nibble)
50 {
51 	PARSE_ASCII_NIBBLE_BAD('\0');
52 
53 	PARSE_ASCII_NIBBLE_BAD('/');
54 	PARSE_ASCII_NIBBLE_OK ('0', 0x0);
55 	PARSE_ASCII_NIBBLE_OK ('1', 0x1);
56 	PARSE_ASCII_NIBBLE_OK ('2', 0x2);
57 	PARSE_ASCII_NIBBLE_OK ('3', 0x3);
58 	PARSE_ASCII_NIBBLE_OK ('4', 0x4);
59 	PARSE_ASCII_NIBBLE_OK ('5', 0x5);
60 	PARSE_ASCII_NIBBLE_OK ('6', 0x6);
61 	PARSE_ASCII_NIBBLE_OK ('7', 0x7);
62 	PARSE_ASCII_NIBBLE_OK ('8', 0x8);
63 	PARSE_ASCII_NIBBLE_OK ('9', 0x9);
64 	PARSE_ASCII_NIBBLE_BAD(':');
65 
66 	PARSE_ASCII_NIBBLE_BAD('@');
67 	PARSE_ASCII_NIBBLE_OK ('A', 0xA);
68 	PARSE_ASCII_NIBBLE_OK ('B', 0xB);
69 	PARSE_ASCII_NIBBLE_OK ('C', 0xC);
70 	PARSE_ASCII_NIBBLE_OK ('D', 0xD);
71 	PARSE_ASCII_NIBBLE_OK ('E', 0xE);
72 	PARSE_ASCII_NIBBLE_OK ('F', 0xF);
73 	PARSE_ASCII_NIBBLE_BAD('G');
74 
75 	PARSE_ASCII_NIBBLE_BAD('`');
76 	PARSE_ASCII_NIBBLE_OK ('a', 0xA);
77 	PARSE_ASCII_NIBBLE_OK ('b', 0xB);
78 	PARSE_ASCII_NIBBLE_OK ('c', 0xC);
79 	PARSE_ASCII_NIBBLE_OK ('d', 0xD);
80 	PARSE_ASCII_NIBBLE_OK ('e', 0xE);
81 	PARSE_ASCII_NIBBLE_OK ('f', 0xF);
82 	PARSE_ASCII_NIBBLE_BAD('g');
83 
84 	PARSE_ASCII_NIBBLE_BAD(0xFF);
85 }
86 
TEST(Util,parse_hex_string)87 TEST(Util, parse_hex_string)
88 {
89 	PARSE_HEX_STRING_OK("");
90 	PARSE_HEX_STRING_OK(" ");
91 	PARSE_HEX_STRING_OK("\t");
92 	PARSE_HEX_STRING_OK("\r");
93 	PARSE_HEX_STRING_OK("\n");
94 
95 	PARSE_HEX_STRING_OK("00",     0x00);
96 	PARSE_HEX_STRING_OK("1002",   0x10, 0x02);
97 	PARSE_HEX_STRING_OK("AAFF",   0xAA, 0xFF);
98 	PARSE_HEX_STRING_OK(" AAFF",  0xAA, 0xFF);
99 	PARSE_HEX_STRING_OK("AA FF",  0xAA, 0xFF);
100 	PARSE_HEX_STRING_OK("AA FF ", 0xAA, 0xFF);
101 	PARSE_HEX_STRING_OK("AAF F",  0xAA, 0xFF);
102 	PARSE_HEX_STRING_OK("A AFF",  0xAA, 0xFF);
103 
104 	PARSE_HEX_STRING_OK("0123456789ABCDEFabcdef",
105 		0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xAB, 0xCD, 0xEF);
106 
107 	PARSE_HEX_STRING_BAD("A");
108 	PARSE_HEX_STRING_BAD("AA B");
109 	PARSE_HEX_STRING_BAD("A BB");
110 	PARSE_HEX_STRING_BAD("ABB");
111 
112 	PARSE_HEX_STRING_BAD("/");
113 	PARSE_HEX_STRING_BAD(":");
114 	PARSE_HEX_STRING_BAD("@");
115 	PARSE_HEX_STRING_BAD("G");
116 	PARSE_HEX_STRING_BAD("`");
117 	PARSE_HEX_STRING_BAD("g");
118 }
119 
TEST(Util,format_offset)120 TEST(Util, format_offset)
121 {
122 	EXPECT_EQ(format_offset(0, OFFSET_BASE_HEX, 0), "0000:0000");
123 	EXPECT_EQ(format_offset(0, OFFSET_BASE_DEC, 0), "0000000000");
124 
125 	EXPECT_EQ(format_offset( 0xABCDEF10LL, OFFSET_BASE_HEX,         0x0LL),         "ABCD:EF10");
126 	EXPECT_EQ(format_offset( 0xABCDEF10LL, OFFSET_BASE_HEX,  0xFFFFFFFFLL),         "ABCD:EF10");
127 	EXPECT_EQ(format_offset( 0xABCDEF10LL, OFFSET_BASE_HEX, 0x100000000LL), "00000000:ABCDEF10");
128 	EXPECT_EQ(format_offset( 0xFFFFFFFFLL, OFFSET_BASE_HEX,         0x0LL),         "FFFF:FFFF");
129 	EXPECT_EQ(format_offset(0x100000000LL, OFFSET_BASE_HEX,         0x0LL), "00000001:00000000");
130 
131 	EXPECT_EQ(format_offset(1234567890LL, OFFSET_BASE_DEC,          0LL),          "1234567890");
132 	EXPECT_EQ(format_offset(1234567890LL, OFFSET_BASE_DEC, 4294967295LL),          "1234567890");
133 	EXPECT_EQ(format_offset(1234567890LL, OFFSET_BASE_DEC, 4294967296LL), "0000000001234567890");
134 	EXPECT_EQ(format_offset(4294967295LL, OFFSET_BASE_DEC,          0LL),          "4294967295");
135 	EXPECT_EQ(format_offset(4294967296LL, OFFSET_BASE_DEC,          0LL), "0000000004294967296");
136 }
137