1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h"
6 
7 #include <cstdint>
8 
9 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
10 #include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
11 
12 namespace spdy {
13 namespace test {
14 namespace {
15 
TEST(SpdyStringUtilsTest,SpdyStrAppend)16 TEST(SpdyStringUtilsTest, SpdyStrAppend) {
17   // No arguments on empty string.
18   std::string output;
19   SpdyStrAppend(&output);
20   EXPECT_TRUE(output.empty());
21 
22   // Single string-like argument.
23   const char kFoo[] = "foo";
24   const std::string string_foo(kFoo);
25   const quiche::QuicheStringPiece stringpiece_foo(string_foo);
26   SpdyStrAppend(&output, kFoo);
27   EXPECT_EQ("foo", output);
28   SpdyStrAppend(&output, string_foo);
29   EXPECT_EQ("foofoo", output);
30   SpdyStrAppend(&output, stringpiece_foo);
31   EXPECT_EQ("foofoofoo", output);
32 
33   // No arguments on non-empty string.
34   SpdyStrAppend(&output);
35   EXPECT_EQ("foofoofoo", output);
36 
37   output.clear();
38 
39   // Two string-like arguments.
40   const char kBar[] = "bar";
41   const quiche::QuicheStringPiece stringpiece_bar(kBar);
42   const std::string string_bar(kBar);
43   SpdyStrAppend(&output, kFoo, kBar);
44   EXPECT_EQ("foobar", output);
45   SpdyStrAppend(&output, kFoo, string_bar);
46   EXPECT_EQ("foobarfoobar", output);
47   SpdyStrAppend(&output, kFoo, stringpiece_bar);
48   EXPECT_EQ("foobarfoobarfoobar", output);
49   SpdyStrAppend(&output, string_foo, kBar);
50   EXPECT_EQ("foobarfoobarfoobarfoobar", output);
51 
52   output.clear();
53 
54   SpdyStrAppend(&output, string_foo, string_bar);
55   EXPECT_EQ("foobar", output);
56   SpdyStrAppend(&output, string_foo, stringpiece_bar);
57   EXPECT_EQ("foobarfoobar", output);
58   SpdyStrAppend(&output, stringpiece_foo, kBar);
59   EXPECT_EQ("foobarfoobarfoobar", output);
60   SpdyStrAppend(&output, stringpiece_foo, string_bar);
61   EXPECT_EQ("foobarfoobarfoobarfoobar", output);
62 
63   output.clear();
64 
65   SpdyStrAppend(&output, stringpiece_foo, stringpiece_bar);
66   EXPECT_EQ("foobar", output);
67 
68   // Many-many arguments.
69   SpdyStrAppend(&output, "foo", "bar", "baz", "qux", "quux", "quuz", "corge",
70                 "grault", "garply", "waldo", "fred", "plugh", "xyzzy", "thud");
71   EXPECT_EQ(
72       "foobarfoobarbazquxquuxquuzcorgegraultgarplywaldofredplughxyzzythud",
73       output);
74 
75   output.clear();
76 
77   // Numerical arguments.
78   const int16_t i = 1;
79   const uint64_t u = 8;
80   const double d = 3.1415;
81 
82   SpdyStrAppend(&output, i, " ", u);
83   EXPECT_EQ("1 8", output);
84   SpdyStrAppend(&output, d, i, i, u, i);
85   EXPECT_EQ("1 83.14151181", output);
86   SpdyStrAppend(&output, "i: ", i, ", u: ", u, ", d: ", d);
87   EXPECT_EQ("1 83.14151181i: 1, u: 8, d: 3.1415", output);
88 
89   output.clear();
90 
91   // Boolean arguments.
92   const bool t = true;
93   const bool f = false;
94 
95   SpdyStrAppend(&output, t);
96   EXPECT_EQ("1", output);
97   SpdyStrAppend(&output, f);
98   EXPECT_EQ("10", output);
99   SpdyStrAppend(&output, f, t, t, f);
100   EXPECT_EQ("100110", output);
101 
102   output.clear();
103 
104   // Mixed string-like, numerical, and Boolean arguments.
105   SpdyStrAppend(&output, kFoo, i, string_foo, f, u, t, stringpiece_bar, d, t);
106   EXPECT_EQ("foo1foo081bar3.14151", output);
107   SpdyStrAppend(&output, d, t, t, string_bar, i, u, kBar, t, d, f);
108   EXPECT_EQ("foo1foo081bar3.141513.141511bar18bar13.14150", output);
109 }
110 
TEST(SpdyStringUtilsTest,SpdyHexDigitToInt)111 TEST(SpdyStringUtilsTest, SpdyHexDigitToInt) {
112   EXPECT_EQ(0, SpdyHexDigitToInt('0'));
113   EXPECT_EQ(1, SpdyHexDigitToInt('1'));
114   EXPECT_EQ(2, SpdyHexDigitToInt('2'));
115   EXPECT_EQ(3, SpdyHexDigitToInt('3'));
116   EXPECT_EQ(4, SpdyHexDigitToInt('4'));
117   EXPECT_EQ(5, SpdyHexDigitToInt('5'));
118   EXPECT_EQ(6, SpdyHexDigitToInt('6'));
119   EXPECT_EQ(7, SpdyHexDigitToInt('7'));
120   EXPECT_EQ(8, SpdyHexDigitToInt('8'));
121   EXPECT_EQ(9, SpdyHexDigitToInt('9'));
122 
123   EXPECT_EQ(10, SpdyHexDigitToInt('a'));
124   EXPECT_EQ(11, SpdyHexDigitToInt('b'));
125   EXPECT_EQ(12, SpdyHexDigitToInt('c'));
126   EXPECT_EQ(13, SpdyHexDigitToInt('d'));
127   EXPECT_EQ(14, SpdyHexDigitToInt('e'));
128   EXPECT_EQ(15, SpdyHexDigitToInt('f'));
129 
130   EXPECT_EQ(10, SpdyHexDigitToInt('A'));
131   EXPECT_EQ(11, SpdyHexDigitToInt('B'));
132   EXPECT_EQ(12, SpdyHexDigitToInt('C'));
133   EXPECT_EQ(13, SpdyHexDigitToInt('D'));
134   EXPECT_EQ(14, SpdyHexDigitToInt('E'));
135   EXPECT_EQ(15, SpdyHexDigitToInt('F'));
136 }
137 
TEST(SpdyStringUtilsTest,SpdyHexDecodeToUInt32)138 TEST(SpdyStringUtilsTest, SpdyHexDecodeToUInt32) {
139   uint32_t out;
140   EXPECT_TRUE(SpdyHexDecodeToUInt32("0", &out));
141   EXPECT_EQ(0u, out);
142   EXPECT_TRUE(SpdyHexDecodeToUInt32("00", &out));
143   EXPECT_EQ(0u, out);
144   EXPECT_TRUE(SpdyHexDecodeToUInt32("0000000", &out));
145   EXPECT_EQ(0u, out);
146   EXPECT_TRUE(SpdyHexDecodeToUInt32("00000000", &out));
147   EXPECT_EQ(0u, out);
148   EXPECT_TRUE(SpdyHexDecodeToUInt32("1", &out));
149   EXPECT_EQ(1u, out);
150   EXPECT_TRUE(SpdyHexDecodeToUInt32("ffffFFF", &out));
151   EXPECT_EQ(0xFFFFFFFu, out);
152   EXPECT_TRUE(SpdyHexDecodeToUInt32("fFfFffFf", &out));
153   EXPECT_EQ(0xFFFFFFFFu, out);
154   EXPECT_TRUE(SpdyHexDecodeToUInt32("01AEF", &out));
155   EXPECT_EQ(0x1AEFu, out);
156   EXPECT_TRUE(SpdyHexDecodeToUInt32("abcde", &out));
157   EXPECT_EQ(0xABCDEu, out);
158 
159   EXPECT_FALSE(SpdyHexDecodeToUInt32("", &out));
160   EXPECT_FALSE(SpdyHexDecodeToUInt32("111111111", &out));
161   EXPECT_FALSE(SpdyHexDecodeToUInt32("1111111111", &out));
162   EXPECT_FALSE(SpdyHexDecodeToUInt32("0x1111", &out));
163 }
164 
TEST(SpdyStringUtilsTest,SpdyHexEncode)165 TEST(SpdyStringUtilsTest, SpdyHexEncode) {
166   unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
167   EXPECT_EQ("01ff02fe038081",
168             SpdyHexEncode(reinterpret_cast<char*>(bytes), sizeof(bytes)));
169 }
170 
TEST(SpdyStringUtilsTest,SpdyHexEncodeUInt32AndTrim)171 TEST(SpdyStringUtilsTest, SpdyHexEncodeUInt32AndTrim) {
172   EXPECT_EQ("0", SpdyHexEncodeUInt32AndTrim(0));
173   EXPECT_EQ("1", SpdyHexEncodeUInt32AndTrim(1));
174   EXPECT_EQ("a", SpdyHexEncodeUInt32AndTrim(0xA));
175   EXPECT_EQ("f", SpdyHexEncodeUInt32AndTrim(0xF));
176   EXPECT_EQ("a9", SpdyHexEncodeUInt32AndTrim(0xA9));
177   EXPECT_EQ("9abcdef", SpdyHexEncodeUInt32AndTrim(0x9ABCDEF));
178   EXPECT_EQ("12345678", SpdyHexEncodeUInt32AndTrim(0x12345678));
179   EXPECT_EQ("ffffffff", SpdyHexEncodeUInt32AndTrim(0xFFFFFFFF));
180   EXPECT_EQ("10000001", SpdyHexEncodeUInt32AndTrim(0x10000001));
181 }
182 
TEST(SpdyStringUtilsTest,SpdyStringPieceCaseHash)183 TEST(SpdyStringUtilsTest, SpdyStringPieceCaseHash) {
184   SpdyStringPieceCaseHash hasher;
185   auto mixed = hasher("To Be Or Not To Be, That is The Question");
186   auto lower = hasher("to be or not to be, that is the question");
187   EXPECT_EQ(mixed, lower);
188   auto lower2 = hasher("to be or not to be, that is the question");
189   EXPECT_EQ(lower, lower2);
190   auto different = hasher("to see or not to see, that is the question");
191   EXPECT_NE(lower, different);
192   EXPECT_NE(lower, hasher(""));
193 }
194 
TEST(SpdyStringUtilsTest,SpdyStringPieceCaseEq)195 TEST(SpdyStringUtilsTest, SpdyStringPieceCaseEq) {
196   SpdyStringPieceCaseEq eq;
197   EXPECT_TRUE(eq("To Be Or Not To Be, That is The Question",
198                  "to be or not to be, that is the question"));
199   EXPECT_TRUE(eq("to be or not to be, that is the question",
200                  "to be or not to be, that is the question"));
201   EXPECT_FALSE(eq("to be or not to be, that is the question",
202                   "to see or not to see, that is the question"));
203 }
204 
205 }  // namespace
206 }  // namespace test
207 }  // namespace spdy
208