rippled
Loading...
Searching...
No Matches
StringUtilities_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Slice.h>
21#include <xrpl/basics/StringUtilities.h>
22#include <xrpl/basics/ToString.h>
23#include <xrpl/beast/unit_test.h>
24
25namespace ripple {
26
28{
29public:
30 void
31 testUnHexSuccess(std::string const& strIn, std::string const& strExpected)
32 {
33 auto rv = strUnHex(strIn);
34 BEAST_EXPECT(rv);
35 BEAST_EXPECT(makeSlice(*rv) == makeSlice(strExpected));
36 }
37
38 void
40 {
41 auto rv = strUnHex(strIn);
42 BEAST_EXPECT(!rv);
43 }
44
45 void
47 {
48 testcase("strUnHex");
49
50 testUnHexSuccess("526970706c6544", "RippleD");
51 testUnHexSuccess("A", "\n");
52 testUnHexSuccess("0A", "\n");
53 testUnHexSuccess("D0A", "\r\n");
54 testUnHexSuccess("0D0A", "\r\n");
55 testUnHexSuccess("200D0A", " \r\n");
56 testUnHexSuccess("282A2B2C2D2E2F29", "(*+,-./)");
57
58 // Check for things which contain some or only invalid characters
59 testUnHexFailure("123X");
61 testUnHexFailure("XRP");
62 }
63
64 void
66 {
67 testcase("parseUrl");
68
69 // Expected passes.
70 {
71 parsedURL pUrl;
72 BEAST_EXPECT(parseUrl(pUrl, "scheme://"));
73 BEAST_EXPECT(pUrl.scheme == "scheme");
74 BEAST_EXPECT(pUrl.username.empty());
75 BEAST_EXPECT(pUrl.password.empty());
76 BEAST_EXPECT(pUrl.domain.empty());
77 BEAST_EXPECT(!pUrl.port);
78 // RFC 3986:
79 // > In general, a URI that uses the generic syntax for authority
80 // with an empty path should be normalized to a path of "/".
81 // Do we want to normalize paths?
82 BEAST_EXPECT(pUrl.path.empty());
83 }
84
85 {
86 parsedURL pUrl;
87 BEAST_EXPECT(parseUrl(pUrl, "scheme:///"));
88 BEAST_EXPECT(pUrl.scheme == "scheme");
89 BEAST_EXPECT(pUrl.username.empty());
90 BEAST_EXPECT(pUrl.password.empty());
91 BEAST_EXPECT(pUrl.domain.empty());
92 BEAST_EXPECT(!pUrl.port);
93 BEAST_EXPECT(pUrl.path == "/");
94 }
95
96 {
97 parsedURL pUrl;
98 BEAST_EXPECT(parseUrl(pUrl, "lower://domain"));
99 BEAST_EXPECT(pUrl.scheme == "lower");
100 BEAST_EXPECT(pUrl.username.empty());
101 BEAST_EXPECT(pUrl.password.empty());
102 BEAST_EXPECT(pUrl.domain == "domain");
103 BEAST_EXPECT(!pUrl.port);
104 BEAST_EXPECT(pUrl.path.empty());
105 }
106
107 {
108 parsedURL pUrl;
109 BEAST_EXPECT(parseUrl(pUrl, "UPPER://domain:234/"));
110 BEAST_EXPECT(pUrl.scheme == "upper");
111 BEAST_EXPECT(pUrl.username.empty());
112 BEAST_EXPECT(pUrl.password.empty());
113 BEAST_EXPECT(pUrl.domain == "domain");
114 BEAST_EXPECT(*pUrl.port == 234);
115 BEAST_EXPECT(pUrl.path == "/");
116 }
117
118 {
119 parsedURL pUrl;
120 BEAST_EXPECT(parseUrl(pUrl, "Mixed://domain/path"));
121 BEAST_EXPECT(pUrl.scheme == "mixed");
122 BEAST_EXPECT(pUrl.username.empty());
123 BEAST_EXPECT(pUrl.password.empty());
124 BEAST_EXPECT(pUrl.domain == "domain");
125 BEAST_EXPECT(!pUrl.port);
126 BEAST_EXPECT(pUrl.path == "/path");
127 }
128
129 {
130 parsedURL pUrl;
131 BEAST_EXPECT(parseUrl(pUrl, "scheme://[::1]:123/path"));
132 BEAST_EXPECT(pUrl.scheme == "scheme");
133 BEAST_EXPECT(pUrl.username.empty());
134 BEAST_EXPECT(pUrl.password.empty());
135 BEAST_EXPECT(pUrl.domain == "::1");
136 BEAST_EXPECT(*pUrl.port == 123);
137 BEAST_EXPECT(pUrl.path == "/path");
138 }
139
140 {
141 parsedURL pUrl;
142 BEAST_EXPECT(
143 parseUrl(pUrl, "scheme://user:pass@domain:123/abc:321"));
144 BEAST_EXPECT(pUrl.scheme == "scheme");
145 BEAST_EXPECT(pUrl.username == "user");
146 BEAST_EXPECT(pUrl.password == "pass");
147 BEAST_EXPECT(pUrl.domain == "domain");
148 BEAST_EXPECT(*pUrl.port == 123);
149 BEAST_EXPECT(pUrl.path == "/abc:321");
150 }
151
152 {
153 parsedURL pUrl;
154 BEAST_EXPECT(parseUrl(pUrl, "scheme://user@domain:123/abc:321"));
155 BEAST_EXPECT(pUrl.scheme == "scheme");
156 BEAST_EXPECT(pUrl.username == "user");
157 BEAST_EXPECT(pUrl.password.empty());
158 BEAST_EXPECT(pUrl.domain == "domain");
159 BEAST_EXPECT(*pUrl.port == 123);
160 BEAST_EXPECT(pUrl.path == "/abc:321");
161 }
162
163 {
164 parsedURL pUrl;
165 BEAST_EXPECT(parseUrl(pUrl, "scheme://:pass@domain:123/abc:321"));
166 BEAST_EXPECT(pUrl.scheme == "scheme");
167 BEAST_EXPECT(pUrl.username.empty());
168 BEAST_EXPECT(pUrl.password == "pass");
169 BEAST_EXPECT(pUrl.domain == "domain");
170 BEAST_EXPECT(*pUrl.port == 123);
171 BEAST_EXPECT(pUrl.path == "/abc:321");
172 }
173
174 {
175 parsedURL pUrl;
176 BEAST_EXPECT(parseUrl(pUrl, "scheme://domain:123/abc:321"));
177 BEAST_EXPECT(pUrl.scheme == "scheme");
178 BEAST_EXPECT(pUrl.username.empty());
179 BEAST_EXPECT(pUrl.password.empty());
180 BEAST_EXPECT(pUrl.domain == "domain");
181 BEAST_EXPECT(*pUrl.port == 123);
182 BEAST_EXPECT(pUrl.path == "/abc:321");
183 }
184
185 {
186 parsedURL pUrl;
187 BEAST_EXPECT(parseUrl(pUrl, "scheme://user:pass@domain/abc:321"));
188 BEAST_EXPECT(pUrl.scheme == "scheme");
189 BEAST_EXPECT(pUrl.username == "user");
190 BEAST_EXPECT(pUrl.password == "pass");
191 BEAST_EXPECT(pUrl.domain == "domain");
192 BEAST_EXPECT(!pUrl.port);
193 BEAST_EXPECT(pUrl.path == "/abc:321");
194 }
195
196 {
197 parsedURL pUrl;
198 BEAST_EXPECT(parseUrl(pUrl, "scheme://user@domain/abc:321"));
199 BEAST_EXPECT(pUrl.scheme == "scheme");
200 BEAST_EXPECT(pUrl.username == "user");
201 BEAST_EXPECT(pUrl.password.empty());
202 BEAST_EXPECT(pUrl.domain == "domain");
203 BEAST_EXPECT(!pUrl.port);
204 BEAST_EXPECT(pUrl.path == "/abc:321");
205 }
206
207 {
208 parsedURL pUrl;
209 BEAST_EXPECT(parseUrl(pUrl, "scheme://:pass@domain/abc:321"));
210 BEAST_EXPECT(pUrl.scheme == "scheme");
211 BEAST_EXPECT(pUrl.username.empty());
212 BEAST_EXPECT(pUrl.password == "pass");
213 BEAST_EXPECT(pUrl.domain == "domain");
214 BEAST_EXPECT(!pUrl.port);
215 BEAST_EXPECT(pUrl.path == "/abc:321");
216 }
217
218 {
219 parsedURL pUrl;
220 BEAST_EXPECT(parseUrl(pUrl, "scheme://domain/abc:321"));
221 BEAST_EXPECT(pUrl.scheme == "scheme");
222 BEAST_EXPECT(pUrl.username.empty());
223 BEAST_EXPECT(pUrl.password.empty());
224 BEAST_EXPECT(pUrl.domain == "domain");
225 BEAST_EXPECT(!pUrl.port);
226 BEAST_EXPECT(pUrl.path == "/abc:321");
227 }
228
229 {
230 parsedURL pUrl;
231 BEAST_EXPECT(parseUrl(pUrl, "scheme:///path/to/file"));
232 BEAST_EXPECT(pUrl.scheme == "scheme");
233 BEAST_EXPECT(pUrl.username.empty());
234 BEAST_EXPECT(pUrl.password.empty());
235 BEAST_EXPECT(pUrl.domain.empty());
236 BEAST_EXPECT(!pUrl.port);
237 BEAST_EXPECT(pUrl.path == "/path/to/file");
238 }
239
240 {
241 parsedURL pUrl;
242 BEAST_EXPECT(
243 parseUrl(pUrl, "scheme://user:pass@domain/path/with/an@sign"));
244 BEAST_EXPECT(pUrl.scheme == "scheme");
245 BEAST_EXPECT(pUrl.username == "user");
246 BEAST_EXPECT(pUrl.password == "pass");
247 BEAST_EXPECT(pUrl.domain == "domain");
248 BEAST_EXPECT(!pUrl.port);
249 BEAST_EXPECT(pUrl.path == "/path/with/an@sign");
250 }
251
252 {
253 parsedURL pUrl;
254 BEAST_EXPECT(parseUrl(pUrl, "scheme://domain/path/with/an@sign"));
255 BEAST_EXPECT(pUrl.scheme == "scheme");
256 BEAST_EXPECT(pUrl.username.empty());
257 BEAST_EXPECT(pUrl.password.empty());
258 BEAST_EXPECT(pUrl.domain == "domain");
259 BEAST_EXPECT(!pUrl.port);
260 BEAST_EXPECT(pUrl.path == "/path/with/an@sign");
261 }
262
263 {
264 parsedURL pUrl;
265 BEAST_EXPECT(parseUrl(pUrl, "scheme://:999/"));
266 BEAST_EXPECT(pUrl.scheme == "scheme");
267 BEAST_EXPECT(pUrl.username.empty());
268 BEAST_EXPECT(pUrl.password.empty());
269 BEAST_EXPECT(pUrl.domain == ":999");
270 BEAST_EXPECT(!pUrl.port);
271 BEAST_EXPECT(pUrl.path == "/");
272 }
273
274 {
275 parsedURL pUrl;
276 BEAST_EXPECT(parseUrl(pUrl, "http://::1:1234/validators"));
277 BEAST_EXPECT(pUrl.scheme == "http");
278 BEAST_EXPECT(pUrl.username.empty());
279 BEAST_EXPECT(pUrl.password.empty());
280 BEAST_EXPECT(pUrl.domain == "::0.1.18.52");
281 BEAST_EXPECT(!pUrl.port);
282 BEAST_EXPECT(pUrl.path == "/validators");
283 }
284
285 // Expected fails.
286 {
287 parsedURL pUrl;
288 BEAST_EXPECT(!parseUrl(pUrl, ""));
289 BEAST_EXPECT(!parseUrl(pUrl, "nonsense"));
290 BEAST_EXPECT(!parseUrl(pUrl, "://"));
291 BEAST_EXPECT(!parseUrl(pUrl, ":///"));
292 BEAST_EXPECT(
293 !parseUrl(pUrl, "scheme://user:pass@domain:65536/abc:321"));
294 BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:23498765/"));
295 BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:0/"));
296 BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:+7/"));
297 BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:-7234/"));
298 BEAST_EXPECT(!parseUrl(pUrl, "UPPER://domain:@#$56!/"));
299 }
300
301 {
302 std::string strUrl("s://" + std::string(8192, ':'));
303 parsedURL pUrl;
304 BEAST_EXPECT(!parseUrl(pUrl, strUrl));
305 }
306 }
307
308 void
310 {
311 testcase("toString");
312 auto result = to_string("hello");
313 BEAST_EXPECT(result == "hello");
314 }
315
316 void
317 run() override
318 {
319 testParseUrl();
320 testUnHex();
321 testToString();
322 }
323};
324
325BEAST_DEFINE_TESTSUITE(StringUtilities, ripple_basics, ripple);
326
327} // namespace ripple
A testsuite class.
Definition: suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:155
void testUnHexSuccess(std::string const &strIn, std::string const &strExpected)
void testUnHexFailure(std::string const &strIn)
void run() override
Runs the suite.
T empty(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:25
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
bool parseUrl(parsedURL &pUrl, std::string const &strUrl)
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:244
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
std::string username
std::string password
std::optional< std::uint16_t > port