1/* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/base/arraysize.h" 12#include "webrtc/base/common.h" 13#include "webrtc/base/gunit.h" 14#include "webrtc/base/stringencode.h" 15#include "webrtc/base/stringutils.h" 16 17namespace rtc { 18 19TEST(Utf8EncodeTest, EncodeDecode) { 20 const struct Utf8Test { 21 const char* encoded; 22 size_t encsize, enclen; 23 unsigned long decoded; 24 } kTests[] = { 25 { "a ", 5, 1, 'a' }, 26 { "\x7F ", 5, 1, 0x7F }, 27 { "\xC2\x80 ", 5, 2, 0x80 }, 28 { "\xDF\xBF ", 5, 2, 0x7FF }, 29 { "\xE0\xA0\x80 ", 5, 3, 0x800 }, 30 { "\xEF\xBF\xBF ", 5, 3, 0xFFFF }, 31 { "\xF0\x90\x80\x80 ", 5, 4, 0x10000 }, 32 { "\xF0\x90\x80\x80 ", 3, 0, 0x10000 }, 33 { "\xF0\xF0\x80\x80 ", 5, 0, 0 }, 34 { "\xF0\x90\x80 ", 5, 0, 0 }, 35 { "\x90\x80\x80 ", 5, 0, 0 }, 36 { NULL, 0, 0 }, 37 }; 38 for (size_t i = 0; kTests[i].encoded; ++i) { 39 unsigned long val = 0; 40 ASSERT_EQ(kTests[i].enclen, utf8_decode(kTests[i].encoded, 41 kTests[i].encsize, 42 &val)); 43 unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded; 44 ASSERT_EQ(result, val); 45 46 if (kTests[i].decoded == 0) { 47 // Not an interesting encoding test case 48 continue; 49 } 50 51 char buffer[5]; 52 memset(buffer, 0x01, arraysize(buffer)); 53 ASSERT_EQ(kTests[i].enclen, utf8_encode(buffer, 54 kTests[i].encsize, 55 kTests[i].decoded)); 56 ASSERT_TRUE(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0); 57 // Make sure remainder of buffer is unchanged 58 ASSERT_TRUE(memory_check(buffer + kTests[i].enclen, 59 0x1, 60 arraysize(buffer) - kTests[i].enclen)); 61 } 62} 63 64class HexEncodeTest : public testing::Test { 65 public: 66 HexEncodeTest() : enc_res_(0), dec_res_(0) { 67 for (size_t i = 0; i < sizeof(data_); ++i) { 68 data_[i] = (i + 128) & 0xff; 69 } 70 memset(decoded_, 0x7f, sizeof(decoded_)); 71 } 72 73 char data_[10]; 74 char encoded_[31]; 75 char decoded_[11]; 76 size_t enc_res_; 77 size_t dec_res_; 78}; 79 80// Test that we can convert to/from hex with no delimiter. 81TEST_F(HexEncodeTest, TestWithNoDelimiter) { 82 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); 83 ASSERT_EQ(sizeof(data_) * 2, enc_res_); 84 ASSERT_STREQ("80818283848586878889", encoded_); 85 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 86 ASSERT_EQ(sizeof(data_), dec_res_); 87 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 88} 89 90// Test that we can convert to/from hex with a colon delimiter. 91TEST_F(HexEncodeTest, TestWithDelimiter) { 92 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 93 data_, sizeof(data_), ':'); 94 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 95 ASSERT_STREQ("80:81:82:83:84:85:86:87:88:89", encoded_); 96 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 97 encoded_, enc_res_, ':'); 98 ASSERT_EQ(sizeof(data_), dec_res_); 99 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 100} 101 102// Test that encoding with one delimiter and decoding with another fails. 103TEST_F(HexEncodeTest, TestWithWrongDelimiter) { 104 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 105 data_, sizeof(data_), ':'); 106 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 107 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 108 encoded_, enc_res_, '/'); 109 ASSERT_EQ(0U, dec_res_); 110} 111 112// Test that encoding without a delimiter and decoding with one fails. 113TEST_F(HexEncodeTest, TestExpectedDelimiter) { 114 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); 115 ASSERT_EQ(sizeof(data_) * 2, enc_res_); 116 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 117 encoded_, enc_res_, ':'); 118 ASSERT_EQ(0U, dec_res_); 119} 120 121// Test that encoding with a delimiter and decoding without one fails. 122TEST_F(HexEncodeTest, TestExpectedNoDelimiter) { 123 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 124 data_, sizeof(data_), ':'); 125 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 126 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 127 ASSERT_EQ(0U, dec_res_); 128} 129 130// Test that we handle a zero-length buffer with no delimiter. 131TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) { 132 enc_res_ = hex_encode(encoded_, sizeof(encoded_), "", 0); 133 ASSERT_EQ(0U, enc_res_); 134 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 135 ASSERT_EQ(0U, dec_res_); 136} 137 138// Test that we handle a zero-length buffer with a delimiter. 139TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) { 140 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), "", 0, ':'); 141 ASSERT_EQ(0U, enc_res_); 142 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 143 encoded_, enc_res_, ':'); 144 ASSERT_EQ(0U, dec_res_); 145} 146 147// Test the std::string variants that take no delimiter. 148TEST_F(HexEncodeTest, TestHelpersNoDelimiter) { 149 std::string result = hex_encode(data_, sizeof(data_)); 150 ASSERT_EQ("80818283848586878889", result); 151 dec_res_ = hex_decode(decoded_, sizeof(decoded_), result); 152 ASSERT_EQ(sizeof(data_), dec_res_); 153 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 154} 155 156// Test the std::string variants that use a delimiter. 157TEST_F(HexEncodeTest, TestHelpersWithDelimiter) { 158 std::string result = hex_encode_with_delimiter(data_, sizeof(data_), ':'); 159 ASSERT_EQ("80:81:82:83:84:85:86:87:88:89", result); 160 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), result, ':'); 161 ASSERT_EQ(sizeof(data_), dec_res_); 162 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 163} 164 165// Test that encoding into a too-small output buffer (without delimiter) fails. 166TEST_F(HexEncodeTest, TestEncodeTooShort) { 167 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 2, 168 data_, sizeof(data_), 0); 169 ASSERT_EQ(0U, enc_res_); 170} 171 172// Test that encoding into a too-small output buffer (with delimiter) fails. 173TEST_F(HexEncodeTest, TestEncodeWithDelimiterTooShort) { 174 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 3 - 1, 175 data_, sizeof(data_), ':'); 176 ASSERT_EQ(0U, enc_res_); 177} 178 179// Test that decoding into a too-small output buffer fails. 180TEST_F(HexEncodeTest, TestDecodeTooShort) { 181 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0); 182 ASSERT_EQ(0U, dec_res_); 183 ASSERT_EQ(0x7f, decoded_[4]); 184} 185 186// Test that decoding non-hex data fails. 187TEST_F(HexEncodeTest, TestDecodeBogusData) { 188 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0); 189 ASSERT_EQ(0U, dec_res_); 190} 191 192// Test that decoding an odd number of hex characters fails. 193TEST_F(HexEncodeTest, TestDecodeOddHexDigits) { 194 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0); 195 ASSERT_EQ(0U, dec_res_); 196} 197 198// Test that decoding a string with too many delimiters fails. 199TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) { 200 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':'); 201 ASSERT_EQ(0U, dec_res_); 202} 203 204// Test that decoding a string with a leading delimiter fails. 205TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) { 206 dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':'); 207 ASSERT_EQ(0U, dec_res_); 208} 209 210// Test that decoding a string with a trailing delimiter fails. 211TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) { 212 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':'); 213 ASSERT_EQ(0U, dec_res_); 214} 215 216// Tests counting substrings. 217TEST(TokenizeTest, CountSubstrings) { 218 std::vector<std::string> fields; 219 220 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields)); 221 fields.clear(); 222 EXPECT_EQ(1ul, tokenize("one", ' ', &fields)); 223 224 // Extra spaces should be ignored. 225 fields.clear(); 226 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields)); 227 fields.clear(); 228 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields)); 229 fields.clear(); 230 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields)); 231} 232 233// Tests comparing substrings. 234TEST(TokenizeTest, CompareSubstrings) { 235 std::vector<std::string> fields; 236 237 tokenize("find middle one", ' ', &fields); 238 ASSERT_EQ(3ul, fields.size()); 239 ASSERT_STREQ("middle", fields.at(1).c_str()); 240 fields.clear(); 241 242 // Extra spaces should be ignored. 243 tokenize(" find middle one ", ' ', &fields); 244 ASSERT_EQ(3ul, fields.size()); 245 ASSERT_STREQ("middle", fields.at(1).c_str()); 246 fields.clear(); 247 tokenize(" ", ' ', &fields); 248 ASSERT_EQ(0ul, fields.size()); 249} 250 251TEST(TokenizeTest, TokenizeAppend) { 252 ASSERT_EQ(0ul, tokenize_append("A B C", ' ', NULL)); 253 254 std::vector<std::string> fields; 255 256 tokenize_append("A B C", ' ', &fields); 257 ASSERT_EQ(3ul, fields.size()); 258 ASSERT_STREQ("B", fields.at(1).c_str()); 259 260 tokenize_append("D E", ' ', &fields); 261 ASSERT_EQ(5ul, fields.size()); 262 ASSERT_STREQ("B", fields.at(1).c_str()); 263 ASSERT_STREQ("E", fields.at(4).c_str()); 264} 265 266TEST(TokenizeTest, TokenizeWithMarks) { 267 ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', NULL)); 268 269 std::vector<std::string> fields; 270 tokenize("A B C", ' ', '"', '"', &fields); 271 ASSERT_EQ(3ul, fields.size()); 272 ASSERT_STREQ("C", fields.at(2).c_str()); 273 274 tokenize("\"A B\" C", ' ', '"', '"', &fields); 275 ASSERT_EQ(2ul, fields.size()); 276 ASSERT_STREQ("A B", fields.at(0).c_str()); 277 278 tokenize("D \"A B\" C", ' ', '"', '"', &fields); 279 ASSERT_EQ(3ul, fields.size()); 280 ASSERT_STREQ("D", fields.at(0).c_str()); 281 ASSERT_STREQ("A B", fields.at(1).c_str()); 282 283 tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields); 284 ASSERT_EQ(4ul, fields.size()); 285 ASSERT_STREQ("D", fields.at(0).c_str()); 286 ASSERT_STREQ("A B", fields.at(1).c_str()); 287 ASSERT_STREQ("E F", fields.at(3).c_str()); 288 289 // No matching marks. 290 tokenize("D \"A B", ' ', '"', '"', &fields); 291 ASSERT_EQ(3ul, fields.size()); 292 ASSERT_STREQ("D", fields.at(0).c_str()); 293 ASSERT_STREQ("\"A", fields.at(1).c_str()); 294 295 tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields); 296 ASSERT_EQ(5ul, fields.size()); 297 ASSERT_STREQ("D", fields.at(0).c_str()); 298 ASSERT_STREQ("A B", fields.at(1).c_str()); 299 ASSERT_STREQ("E F", fields.at(3).c_str()); 300} 301 302TEST(TokenizeTest, TokenizeWithEmptyTokens) { 303 std::vector<std::string> fields; 304 EXPECT_EQ(3ul, tokenize_with_empty_tokens("a.b.c", '.', &fields)); 305 EXPECT_EQ("a", fields[0]); 306 EXPECT_EQ("b", fields[1]); 307 EXPECT_EQ("c", fields[2]); 308 309 EXPECT_EQ(3ul, tokenize_with_empty_tokens("..c", '.', &fields)); 310 EXPECT_TRUE(fields[0].empty()); 311 EXPECT_TRUE(fields[1].empty()); 312 EXPECT_EQ("c", fields[2]); 313 314 EXPECT_EQ(1ul, tokenize_with_empty_tokens("", '.', &fields)); 315 EXPECT_TRUE(fields[0].empty()); 316} 317 318TEST(TokenizeFirstTest, NoLeadingSpaces) { 319 std::string token; 320 std::string rest; 321 322 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest)); 323 ASSERT_STREQ("A", token.c_str()); 324 ASSERT_STREQ("&*${}", rest.c_str()); 325 326 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest)); 327 ASSERT_STREQ("A", token.c_str()); 328 ASSERT_STREQ("B& *${}", rest.c_str()); 329 330 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest)); 331 ASSERT_STREQ("A", token.c_str()); 332 ASSERT_STREQ("B& *${} ", rest.c_str()); 333} 334 335TEST(TokenizeFirstTest, LeadingSpaces) { 336 std::string token; 337 std::string rest; 338 339 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest)); 340 ASSERT_STREQ("", token.c_str()); 341 ASSERT_STREQ("A B C", rest.c_str()); 342 343 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest)); 344 ASSERT_STREQ("", token.c_str()); 345 ASSERT_STREQ("A B C ", rest.c_str()); 346} 347 348TEST(TokenizeFirstTest, SingleToken) { 349 std::string token; 350 std::string rest; 351 352 // In the case where we cannot find delimiter the whole string is a token. 353 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest)); 354 355 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest)); 356 ASSERT_STREQ("ABC", token.c_str()); 357 ASSERT_STREQ("", rest.c_str()); 358 359 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest)); 360 ASSERT_STREQ("", token.c_str()); 361 ASSERT_STREQ("ABC ", rest.c_str()); 362} 363 364// Tests counting substrings. 365TEST(SplitTest, CountSubstrings) { 366 std::vector<std::string> fields; 367 368 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields)); 369 fields.clear(); 370 EXPECT_EQ(1ul, split("one", ',', &fields)); 371 372 // Empty fields between commas count. 373 fields.clear(); 374 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields)); 375 fields.clear(); 376 EXPECT_EQ(3ul, split(",three,", ',', &fields)); 377 fields.clear(); 378 EXPECT_EQ(1ul, split("", ',', &fields)); 379} 380 381// Tests comparing substrings. 382TEST(SplitTest, CompareSubstrings) { 383 std::vector<std::string> fields; 384 385 split("find,middle,one", ',', &fields); 386 ASSERT_EQ(3ul, fields.size()); 387 ASSERT_STREQ("middle", fields.at(1).c_str()); 388 fields.clear(); 389 390 // Empty fields between commas count. 391 split("find,,middle,one", ',', &fields); 392 ASSERT_EQ(4ul, fields.size()); 393 ASSERT_STREQ("middle", fields.at(2).c_str()); 394 fields.clear(); 395 split("", ',', &fields); 396 ASSERT_EQ(1ul, fields.size()); 397 ASSERT_STREQ("", fields.at(0).c_str()); 398} 399 400TEST(BoolTest, DecodeValid) { 401 bool value; 402 EXPECT_TRUE(FromString("true", &value)); 403 EXPECT_TRUE(value); 404 EXPECT_TRUE(FromString("true,", &value)); 405 EXPECT_TRUE(value); 406 EXPECT_TRUE(FromString("true , true", &value)); 407 EXPECT_TRUE(value); 408 EXPECT_TRUE(FromString("true ,\n false", &value)); 409 EXPECT_TRUE(value); 410 EXPECT_TRUE(FromString(" true \n", &value)); 411 EXPECT_TRUE(value); 412 413 EXPECT_TRUE(FromString("false", &value)); 414 EXPECT_FALSE(value); 415 EXPECT_TRUE(FromString(" false ", &value)); 416 EXPECT_FALSE(value); 417 EXPECT_TRUE(FromString(" false, ", &value)); 418 EXPECT_FALSE(value); 419 420 EXPECT_TRUE(FromString<bool>("true\n")); 421 EXPECT_FALSE(FromString<bool>("false\n")); 422} 423 424TEST(BoolTest, DecodeInvalid) { 425 bool value; 426 EXPECT_FALSE(FromString("True", &value)); 427 EXPECT_FALSE(FromString("TRUE", &value)); 428 EXPECT_FALSE(FromString("False", &value)); 429 EXPECT_FALSE(FromString("FALSE", &value)); 430 EXPECT_FALSE(FromString("0", &value)); 431 EXPECT_FALSE(FromString("1", &value)); 432 EXPECT_FALSE(FromString("0,", &value)); 433 EXPECT_FALSE(FromString("1,", &value)); 434 EXPECT_FALSE(FromString("1,0", &value)); 435 EXPECT_FALSE(FromString("1.", &value)); 436 EXPECT_FALSE(FromString("1.0", &value)); 437 EXPECT_FALSE(FromString("", &value)); 438 EXPECT_FALSE(FromString<bool>("false\nfalse")); 439} 440 441TEST(BoolTest, RoundTrip) { 442 bool value; 443 EXPECT_TRUE(FromString(ToString(true), &value)); 444 EXPECT_TRUE(value); 445 EXPECT_TRUE(FromString(ToString(false), &value)); 446 EXPECT_FALSE(value); 447} 448 449} // namespace rtc 450