xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
tests
libxrpl
basics
tests/libxrpl/basics/StringUtilities.cpp
1
#include <xrpl/basics/StringUtilities.h>
2
3
#include <xrpl/basics/Slice.h>
4
#include <xrpl/basics/ToString.h>
5
6
#include <gtest/gtest.h>
7
8
#include <
string
>
9
10
namespace
xrpl
{
11
12
class
StringUtilitiesTest
:
public
::testing::Test
13
{
14
public
:
15
static
void
16
testUnHexSuccess
(
std::string
const
& strIn,
std::string
const
& strExpected)
17
{
18
auto
rv =
strUnHex
(strIn);
19
EXPECT_TRUE(rv);
20
21
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
22
EXPECT_EQ(
makeSlice
(*rv),
makeSlice
(strExpected));
23
}
24
25
static
void
26
testUnHexFailure
(
std::string
const
& strIn)
27
{
28
auto
rv =
strUnHex
(strIn);
29
EXPECT_FALSE(rv);
30
}
31
};
32
33
TEST_F
(
StringUtilitiesTest
, un_hex)
34
{
35
testUnHexSuccess(
"526970706c6544"
,
"RippleD"
);
36
testUnHexSuccess(
"A"
,
"\n"
);
37
testUnHexSuccess(
"0A"
,
"\n"
);
38
testUnHexSuccess(
"D0A"
,
"\r\n"
);
39
testUnHexSuccess(
"0D0A"
,
"\r\n"
);
40
testUnHexSuccess(
"200D0A"
,
" \r\n"
);
41
testUnHexSuccess(
"282A2B2C2D2E2F29"
,
"(*+,-./)"
);
42
43
// Check for things which contain some or only invalid characters
44
testUnHexFailure(
"123X"
);
45
testUnHexFailure(
"V"
);
46
testUnHexFailure(
"XRP"
);
47
}
48
49
TEST_F
(
StringUtilitiesTest
, parse_url)
50
{
51
// Expected passes.
52
{
53
ParsedUrl
pUrl;
54
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://"
));
55
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
56
EXPECT_TRUE(pUrl.
username
.
empty
());
57
EXPECT_TRUE(pUrl.
password
.
empty
());
58
EXPECT_TRUE(pUrl.
domain
.
empty
());
59
EXPECT_FALSE(pUrl.
port
);
60
// RFC 3986:
61
// > In general, a URI that uses the generic syntax for authority
62
// with an empty path should be normalized to a path of "/".
63
// Do we want to normalize paths?
64
EXPECT_TRUE(pUrl.
path
.
empty
());
65
}
66
67
{
68
ParsedUrl
pUrl;
69
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme:///"
));
70
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
71
EXPECT_TRUE(pUrl.
username
.
empty
());
72
EXPECT_TRUE(pUrl.
password
.
empty
());
73
EXPECT_TRUE(pUrl.
domain
.
empty
());
74
EXPECT_FALSE(pUrl.
port
);
75
EXPECT_EQ(pUrl.
path
,
"/"
);
76
}
77
78
{
79
ParsedUrl
pUrl;
80
EXPECT_TRUE(
parseUrl
(pUrl,
"lower://domain"
));
81
EXPECT_EQ(pUrl.
scheme
,
"lower"
);
82
EXPECT_TRUE(pUrl.
username
.
empty
());
83
EXPECT_TRUE(pUrl.
password
.
empty
());
84
EXPECT_EQ(pUrl.
domain
,
"domain"
);
85
EXPECT_FALSE(pUrl.
port
);
86
EXPECT_TRUE(pUrl.
path
.
empty
());
87
}
88
89
{
90
ParsedUrl
pUrl;
91
EXPECT_TRUE(
parseUrl
(pUrl,
"UPPER://domain:234/"
));
92
EXPECT_EQ(pUrl.
scheme
,
"upper"
);
93
EXPECT_TRUE(pUrl.
username
.
empty
());
94
EXPECT_TRUE(pUrl.
password
.
empty
());
95
EXPECT_EQ(pUrl.
domain
,
"domain"
);
96
EXPECT_EQ(*pUrl.
port
, 234);
// NOLINT(bugprone-unchecked-optional-access)
97
EXPECT_EQ(pUrl.
path
,
"/"
);
98
}
99
100
{
101
ParsedUrl
pUrl;
102
EXPECT_TRUE(
parseUrl
(pUrl,
"Mixed://domain/path"
));
103
EXPECT_EQ(pUrl.
scheme
,
"mixed"
);
104
EXPECT_TRUE(pUrl.
username
.
empty
());
105
EXPECT_TRUE(pUrl.
password
.
empty
());
106
EXPECT_EQ(pUrl.
domain
,
"domain"
);
107
EXPECT_FALSE(pUrl.
port
);
108
EXPECT_EQ(pUrl.
path
,
"/path"
);
109
}
110
111
{
112
ParsedUrl
pUrl;
113
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://[::1]:123/path"
));
114
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
115
EXPECT_TRUE(pUrl.
username
.
empty
());
116
EXPECT_TRUE(pUrl.
password
.
empty
());
117
EXPECT_EQ(pUrl.
domain
,
"::1"
);
118
EXPECT_EQ(*pUrl.
port
, 123);
// NOLINT(bugprone-unchecked-optional-access)
119
EXPECT_EQ(pUrl.
path
,
"/path"
);
120
}
121
122
{
123
ParsedUrl
pUrl;
124
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://user:pass@domain:123/abc:321"
));
125
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
126
EXPECT_EQ(pUrl.
username
,
"user"
);
127
EXPECT_EQ(pUrl.
password
,
"pass"
);
128
EXPECT_EQ(pUrl.
domain
,
"domain"
);
129
EXPECT_EQ(*pUrl.
port
, 123);
// NOLINT(bugprone-unchecked-optional-access)
130
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
131
}
132
133
{
134
ParsedUrl
pUrl;
135
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://user@domain:123/abc:321"
));
136
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
137
EXPECT_EQ(pUrl.
username
,
"user"
);
138
EXPECT_TRUE(pUrl.
password
.
empty
());
139
EXPECT_EQ(pUrl.
domain
,
"domain"
);
140
EXPECT_EQ(*pUrl.
port
, 123);
// NOLINT(bugprone-unchecked-optional-access)
141
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
142
}
143
144
{
145
ParsedUrl
pUrl;
146
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://:pass@domain:123/abc:321"
));
147
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
148
EXPECT_TRUE(pUrl.
username
.
empty
());
149
EXPECT_EQ(pUrl.
password
,
"pass"
);
150
EXPECT_EQ(pUrl.
domain
,
"domain"
);
151
EXPECT_EQ(*pUrl.
port
, 123);
// NOLINT(bugprone-unchecked-optional-access)
152
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
153
}
154
155
{
156
ParsedUrl
pUrl;
157
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://domain:123/abc:321"
));
158
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
159
EXPECT_TRUE(pUrl.
username
.
empty
());
160
EXPECT_TRUE(pUrl.
password
.
empty
());
161
EXPECT_EQ(pUrl.
domain
,
"domain"
);
162
EXPECT_EQ(*pUrl.
port
, 123);
// NOLINT(bugprone-unchecked-optional-access)
163
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
164
}
165
166
{
167
ParsedUrl
pUrl;
168
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://user:pass@domain/abc:321"
));
169
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
170
EXPECT_EQ(pUrl.
username
,
"user"
);
171
EXPECT_EQ(pUrl.
password
,
"pass"
);
172
EXPECT_EQ(pUrl.
domain
,
"domain"
);
173
EXPECT_FALSE(pUrl.
port
);
174
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
175
}
176
177
{
178
ParsedUrl
pUrl;
179
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://user@domain/abc:321"
));
180
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
181
EXPECT_EQ(pUrl.
username
,
"user"
);
182
EXPECT_TRUE(pUrl.
password
.
empty
());
183
EXPECT_EQ(pUrl.
domain
,
"domain"
);
184
EXPECT_FALSE(pUrl.
port
);
185
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
186
}
187
188
{
189
ParsedUrl
pUrl;
190
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://:pass@domain/abc:321"
));
191
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
192
EXPECT_TRUE(pUrl.
username
.
empty
());
193
EXPECT_EQ(pUrl.
password
,
"pass"
);
194
EXPECT_EQ(pUrl.
domain
,
"domain"
);
195
EXPECT_FALSE(pUrl.
port
);
196
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
197
}
198
199
{
200
ParsedUrl
pUrl;
201
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://domain/abc:321"
));
202
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
203
EXPECT_TRUE(pUrl.
username
.
empty
());
204
EXPECT_TRUE(pUrl.
password
.
empty
());
205
EXPECT_EQ(pUrl.
domain
,
"domain"
);
206
EXPECT_FALSE(pUrl.
port
);
207
EXPECT_EQ(pUrl.
path
,
"/abc:321"
);
208
}
209
210
{
211
ParsedUrl
pUrl;
212
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme:///path/to/file"
));
213
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
214
EXPECT_TRUE(pUrl.
username
.
empty
());
215
EXPECT_TRUE(pUrl.
password
.
empty
());
216
EXPECT_TRUE(pUrl.
domain
.
empty
());
217
EXPECT_FALSE(pUrl.
port
);
218
EXPECT_EQ(pUrl.
path
,
"/path/to/file"
);
219
}
220
221
{
222
ParsedUrl
pUrl;
223
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://user:pass@domain/path/with/an@sign"
));
224
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
225
EXPECT_EQ(pUrl.
username
,
"user"
);
226
EXPECT_EQ(pUrl.
password
,
"pass"
);
227
EXPECT_EQ(pUrl.
domain
,
"domain"
);
228
EXPECT_FALSE(pUrl.
port
);
229
EXPECT_EQ(pUrl.
path
,
"/path/with/an@sign"
);
230
}
231
232
{
233
ParsedUrl
pUrl;
234
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://domain/path/with/an@sign"
));
235
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
236
EXPECT_TRUE(pUrl.
username
.
empty
());
237
EXPECT_TRUE(pUrl.
password
.
empty
());
238
EXPECT_EQ(pUrl.
domain
,
"domain"
);
239
EXPECT_FALSE(pUrl.
port
);
240
EXPECT_EQ(pUrl.
path
,
"/path/with/an@sign"
);
241
}
242
243
{
244
ParsedUrl
pUrl;
245
EXPECT_TRUE(
parseUrl
(pUrl,
"scheme://:999/"
));
246
EXPECT_EQ(pUrl.
scheme
,
"scheme"
);
247
EXPECT_TRUE(pUrl.
username
.
empty
());
248
EXPECT_TRUE(pUrl.
password
.
empty
());
249
EXPECT_EQ(pUrl.
domain
,
":999"
);
250
EXPECT_FALSE(pUrl.
port
);
251
EXPECT_EQ(pUrl.
path
,
"/"
);
252
}
253
254
{
255
ParsedUrl
pUrl;
256
EXPECT_TRUE(
parseUrl
(pUrl,
"http://::1:1234/validators"
));
257
EXPECT_EQ(pUrl.
scheme
,
"http"
);
258
EXPECT_TRUE(pUrl.
username
.
empty
());
259
EXPECT_TRUE(pUrl.
password
.
empty
());
260
EXPECT_EQ(pUrl.
domain
,
"::0.1.18.52"
);
261
EXPECT_FALSE(pUrl.
port
);
262
EXPECT_EQ(pUrl.
path
,
"/validators"
);
263
}
264
265
// Expected fails.
266
{
267
ParsedUrl
pUrl;
268
EXPECT_FALSE(
parseUrl
(pUrl,
""
));
269
EXPECT_FALSE(
parseUrl
(pUrl,
"nonsense"
));
270
EXPECT_FALSE(
parseUrl
(pUrl,
"://"
));
271
EXPECT_FALSE(
parseUrl
(pUrl,
":///"
));
272
EXPECT_FALSE(
parseUrl
(pUrl,
"scheme://user:pass@domain:65536/abc:321"
));
273
EXPECT_FALSE(
parseUrl
(pUrl,
"UPPER://domain:23498765/"
));
274
EXPECT_FALSE(
parseUrl
(pUrl,
"UPPER://domain:0/"
));
275
EXPECT_FALSE(
parseUrl
(pUrl,
"UPPER://domain:+7/"
));
276
EXPECT_FALSE(
parseUrl
(pUrl,
"UPPER://domain:-7234/"
));
277
EXPECT_FALSE(
parseUrl
(pUrl,
"UPPER://domain:@#$56!/"
));
278
}
279
280
{
281
std::string
const
strUrl(
"s://"
+
std::string
(8192,
':'
));
282
ParsedUrl
pUrl;
283
EXPECT_FALSE(
parseUrl
(pUrl, strUrl));
284
}
285
}
286
287
TEST_F
(
StringUtilitiesTest
,
to_string
)
288
{
289
auto
result =
to_string
(
"hello"
);
290
EXPECT_EQ(result,
"hello"
);
291
}
292
293
TEST_F
(
StringUtilitiesTest
, trim_whitespace)
294
{
295
EXPECT_EQ(
trimWhitespace
(
""
),
""
);
296
EXPECT_EQ(
trimWhitespace
(
" "
),
""
);
297
EXPECT_EQ(
trimWhitespace
(
"abc"
),
"abc"
);
298
EXPECT_EQ(
trimWhitespace
(
" abc"
),
"abc"
);
299
EXPECT_EQ(
trimWhitespace
(
"abc "
),
"abc"
);
300
EXPECT_EQ(
trimWhitespace
(
" \t\n\v\f\r abc \t\n\v\f\r "
),
"abc"
);
301
302
// Interior whitespace is preserved.
303
EXPECT_EQ(
trimWhitespace
(
" a b\tc "
),
"a b\tc"
);
304
}
305
306
TEST_F
(
StringUtilitiesTest
, to_lower)
307
{
308
EXPECT_EQ(
toLower
(
""
),
""
);
309
EXPECT_EQ(
toLower
(
"ABC"
),
"abc"
);
310
EXPECT_EQ(
toLower
(
"AbC123"
),
"abc123"
);
311
EXPECT_EQ(
toLower
(
"already lower"
),
"already lower"
);
312
313
// Only 'A'-'Z' are remapped. Neighbouring punctuation and digits, which a
314
// buggy range check could catch, must survive untouched.
315
EXPECT_EQ(
toLower
(
"@[`{_^"
),
"@[`{_^"
);
316
}
317
318
// Both helpers are documented as depending only on their input. Guard that by
319
// checking the bytes just outside ASCII, which a locale-aware isspace/tolower
320
// could classify differently.
321
TEST_F
(
StringUtilitiesTest
, trim_and_lower_ignore_locale)
322
{
323
// 0xA0 is NO-BREAK SPACE in Latin-1 and is whitespace to some locales.
324
std::string
const
nbsp(
"\xA0"
, 1);
325
EXPECT_EQ(
trimWhitespace
(nbsp), nbsp);
326
EXPECT_EQ(
trimWhitespace
(
" "
+ nbsp +
" "
), nbsp);
327
328
// 0xC0 is LATIN CAPITAL LETTER A WITH GRAVE in Latin-1.
329
std::string
const
agrave(
"\xC0"
, 1);
330
EXPECT_EQ(
toLower
(agrave), agrave);
331
}
332
333
}
// namespace xrpl
std::string
xrpl::StringUtilitiesTest
Definition
tests/libxrpl/basics/StringUtilities.cpp:13
xrpl::StringUtilitiesTest::testUnHexFailure
static void testUnHexFailure(std::string const &strIn)
Definition
tests/libxrpl/basics/StringUtilities.cpp:26
xrpl::StringUtilitiesTest::testUnHexSuccess
static void testUnHexSuccess(std::string const &strIn, std::string const &strExpected)
Definition
tests/libxrpl/basics/StringUtilities.cpp:16
std::string::empty
T empty(T... args)
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::toLower
std::string toLower(std::string str)
Fold ASCII upper case letters to lower case.
Definition
libxrpl/basics/StringUtilities.cpp:129
xrpl::TEST_F
TEST_F(HardenedHashTest, user_types)
Definition
hardened_hash.cpp:213
xrpl::trimWhitespace
std::string trimWhitespace(std::string str)
Remove leading and trailing ASCII whitespace.
Definition
libxrpl/basics/StringUtilities.cpp:119
xrpl::to_string
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition
base_uint.h:657
xrpl::makeSlice
Slice makeSlice(std::array< T, N > const &a)
Definition
Slice.h:228
xrpl::strUnHex
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition
StringUtilities.h:64
xrpl::parseUrl
bool parseUrl(ParsedUrl &pUrl, std::string const &strUrl)
Definition
libxrpl/basics/StringUtilities.cpp:37
string
xrpl::ParsedUrl
Definition
StringUtilities.h:106
xrpl::ParsedUrl::port
std::optional< std::uint16_t > port
Definition
StringUtilities.h:113
xrpl::ParsedUrl::password
std::string password
Definition
StringUtilities.h:111
xrpl::ParsedUrl::scheme
std::string scheme
Definition
StringUtilities.h:109
xrpl::ParsedUrl::domain
std::string domain
Definition
StringUtilities.h:112
xrpl::ParsedUrl::path
std::string path
Definition
StringUtilities.h:114
xrpl::ParsedUrl::username
std::string username
Definition
StringUtilities.h:110
Generated by
1.17.0