1 /* 2 * libjingle 3 * Copyright 2004, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/base/common.h" 29 #include "talk/base/gunit.h" 30 #include "talk/base/stringencode.h" 31 #include "talk/base/stringutils.h" 32 33 namespace talk_base { 34 35 TEST(Utf8EncodeTest, EncodeDecode) { 36 const struct Utf8Test { 37 const char* encoded; 38 size_t encsize, enclen; 39 unsigned long decoded; 40 } kTests[] = { 41 { "a ", 5, 1, 'a' }, 42 { "\x7F ", 5, 1, 0x7F }, 43 { "\xC2\x80 ", 5, 2, 0x80 }, 44 { "\xDF\xBF ", 5, 2, 0x7FF }, 45 { "\xE0\xA0\x80 ", 5, 3, 0x800 }, 46 { "\xEF\xBF\xBF ", 5, 3, 0xFFFF }, 47 { "\xF0\x90\x80\x80 ", 5, 4, 0x10000 }, 48 { "\xF0\x90\x80\x80 ", 3, 0, 0x10000 }, 49 { "\xF0\xF0\x80\x80 ", 5, 0, 0 }, 50 { "\xF0\x90\x80 ", 5, 0, 0 }, 51 { "\x90\x80\x80 ", 5, 0, 0 }, 52 { NULL, 0, 0 }, 53 }; 54 for (size_t i = 0; kTests[i].encoded; ++i) { 55 unsigned long val = 0; 56 ASSERT_EQ(kTests[i].enclen, utf8_decode(kTests[i].encoded, 57 kTests[i].encsize, 58 &val)); 59 unsigned long result = (kTests[i].enclen == 0) ? 0 : kTests[i].decoded; 60 ASSERT_EQ(result, val); 61 62 if (kTests[i].decoded == 0) { 63 // Not an interesting encoding test case 64 continue; 65 } 66 67 char buffer[5]; 68 memset(buffer, 0x01, ARRAY_SIZE(buffer)); 69 ASSERT_EQ(kTests[i].enclen, utf8_encode(buffer, 70 kTests[i].encsize, 71 kTests[i].decoded)); 72 ASSERT_TRUE(memcmp(buffer, kTests[i].encoded, kTests[i].enclen) == 0); 73 // Make sure remainder of buffer is unchanged 74 ASSERT_TRUE(memory_check(buffer + kTests[i].enclen, 75 0x1, 76 ARRAY_SIZE(buffer) - kTests[i].enclen)); 77 } 78 } 79 80 class HexEncodeTest : public testing::Test { 81 public: 82 HexEncodeTest() : enc_res_(0), dec_res_(0) { 83 for (size_t i = 0; i < sizeof(data_); ++i) { 84 data_[i] = (i + 128) & 0xff; 85 } 86 memset(decoded_, 0x7f, sizeof(decoded_)); 87 } 88 89 char data_[10]; 90 char encoded_[31]; 91 char decoded_[11]; 92 size_t enc_res_; 93 size_t dec_res_; 94 }; 95 96 // Test that we can convert to/from hex with no delimiter. 97 TEST_F(HexEncodeTest, TestWithNoDelimiter) { 98 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); 99 ASSERT_EQ(sizeof(data_) * 2, enc_res_); 100 ASSERT_STREQ("80818283848586878889", encoded_); 101 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 102 ASSERT_EQ(sizeof(data_), dec_res_); 103 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 104 } 105 106 // Test that we can convert to/from hex with a colon delimiter. 107 TEST_F(HexEncodeTest, TestWithDelimiter) { 108 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 109 data_, sizeof(data_), ':'); 110 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 111 ASSERT_STREQ("80:81:82:83:84:85:86:87:88:89", encoded_); 112 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 113 encoded_, enc_res_, ':'); 114 ASSERT_EQ(sizeof(data_), dec_res_); 115 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 116 } 117 118 // Test that encoding with one delimiter and decoding with another fails. 119 TEST_F(HexEncodeTest, TestWithWrongDelimiter) { 120 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 121 data_, sizeof(data_), ':'); 122 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 123 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 124 encoded_, enc_res_, '/'); 125 ASSERT_EQ(0U, dec_res_); 126 } 127 128 // Test that encoding without a delimiter and decoding with one fails. 129 TEST_F(HexEncodeTest, TestExpectedDelimiter) { 130 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_)); 131 ASSERT_EQ(sizeof(data_) * 2, enc_res_); 132 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 133 encoded_, enc_res_, ':'); 134 ASSERT_EQ(0U, dec_res_); 135 } 136 137 // Test that encoding with a delimiter and decoding without one fails. 138 TEST_F(HexEncodeTest, TestExpectedNoDelimiter) { 139 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), 140 data_, sizeof(data_), ':'); 141 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_); 142 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 143 ASSERT_EQ(0U, dec_res_); 144 } 145 146 // Test that we handle a zero-length buffer with no delimiter. 147 TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) { 148 enc_res_ = hex_encode(encoded_, sizeof(encoded_), "", 0); 149 ASSERT_EQ(0U, enc_res_); 150 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_); 151 ASSERT_EQ(0U, dec_res_); 152 } 153 154 // Test that we handle a zero-length buffer with a delimiter. 155 TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) { 156 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), "", 0, ':'); 157 ASSERT_EQ(0U, enc_res_); 158 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), 159 encoded_, enc_res_, ':'); 160 ASSERT_EQ(0U, dec_res_); 161 } 162 163 // Test the std::string variants that take no delimiter. 164 TEST_F(HexEncodeTest, TestHelpersNoDelimiter) { 165 std::string result = hex_encode(data_, sizeof(data_)); 166 ASSERT_EQ("80818283848586878889", result); 167 dec_res_ = hex_decode(decoded_, sizeof(decoded_), result); 168 ASSERT_EQ(sizeof(data_), dec_res_); 169 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 170 } 171 172 // Test the std::string variants that use a delimiter. 173 TEST_F(HexEncodeTest, TestHelpersWithDelimiter) { 174 std::string result = hex_encode_with_delimiter(data_, sizeof(data_), ':'); 175 ASSERT_EQ("80:81:82:83:84:85:86:87:88:89", result); 176 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), result, ':'); 177 ASSERT_EQ(sizeof(data_), dec_res_); 178 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); 179 } 180 181 // Test that encoding into a too-small output buffer (without delimiter) fails. 182 TEST_F(HexEncodeTest, TestEncodeTooShort) { 183 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 2, 184 data_, sizeof(data_), 0); 185 ASSERT_EQ(0U, enc_res_); 186 } 187 188 // Test that encoding into a too-small output buffer (with delimiter) fails. 189 TEST_F(HexEncodeTest, TestEncodeWithDelimiterTooShort) { 190 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 3 - 1, 191 data_, sizeof(data_), ':'); 192 ASSERT_EQ(0U, enc_res_); 193 } 194 195 // Test that decoding into a too-small output buffer fails. 196 TEST_F(HexEncodeTest, TestDecodeTooShort) { 197 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0); 198 ASSERT_EQ(0U, dec_res_); 199 ASSERT_EQ(0x7f, decoded_[4]); 200 } 201 202 // Test that decoding non-hex data fails. 203 TEST_F(HexEncodeTest, TestDecodeBogusData) { 204 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0); 205 ASSERT_EQ(0U, dec_res_); 206 } 207 208 // Test that decoding an odd number of hex characters fails. 209 TEST_F(HexEncodeTest, TestDecodeOddHexDigits) { 210 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0); 211 ASSERT_EQ(0U, dec_res_); 212 } 213 214 // Test that decoding a string with too many delimiters fails. 215 TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) { 216 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':'); 217 ASSERT_EQ(0U, dec_res_); 218 } 219 220 // Test that decoding a string with a leading delimiter fails. 221 TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) { 222 dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':'); 223 ASSERT_EQ(0U, dec_res_); 224 } 225 226 // Test that decoding a string with a trailing delimiter fails. 227 TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) { 228 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':'); 229 ASSERT_EQ(0U, dec_res_); 230 } 231 232 // Tests counting substrings. 233 TEST(TokenizeTest, CountSubstrings) { 234 std::vector<std::string> fields; 235 236 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields)); 237 fields.clear(); 238 EXPECT_EQ(1ul, tokenize("one", ' ', &fields)); 239 240 // Extra spaces should be ignored. 241 fields.clear(); 242 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields)); 243 fields.clear(); 244 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields)); 245 fields.clear(); 246 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields)); 247 } 248 249 // Tests comparing substrings. 250 TEST(TokenizeTest, CompareSubstrings) { 251 std::vector<std::string> fields; 252 253 tokenize("find middle one", ' ', &fields); 254 ASSERT_EQ(3ul, fields.size()); 255 ASSERT_STREQ("middle", fields.at(1).c_str()); 256 fields.clear(); 257 258 // Extra spaces should be ignored. 259 tokenize(" find middle one ", ' ', &fields); 260 ASSERT_EQ(3ul, fields.size()); 261 ASSERT_STREQ("middle", fields.at(1).c_str()); 262 fields.clear(); 263 tokenize(" ", ' ', &fields); 264 ASSERT_EQ(0ul, fields.size()); 265 } 266 267 TEST(TokenizeTest, TokenizeAppend) { 268 ASSERT_EQ(0ul, tokenize_append("A B C", ' ', NULL)); 269 270 std::vector<std::string> fields; 271 272 tokenize_append("A B C", ' ', &fields); 273 ASSERT_EQ(3ul, fields.size()); 274 ASSERT_STREQ("B", fields.at(1).c_str()); 275 276 tokenize_append("D E", ' ', &fields); 277 ASSERT_EQ(5ul, fields.size()); 278 ASSERT_STREQ("B", fields.at(1).c_str()); 279 ASSERT_STREQ("E", fields.at(4).c_str()); 280 } 281 282 TEST(TokenizeTest, TokenizeWithMarks) { 283 ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', NULL)); 284 285 std::vector<std::string> fields; 286 tokenize("A B C", ' ', '"', '"', &fields); 287 ASSERT_EQ(3ul, fields.size()); 288 ASSERT_STREQ("C", fields.at(2).c_str()); 289 290 tokenize("\"A B\" C", ' ', '"', '"', &fields); 291 ASSERT_EQ(2ul, fields.size()); 292 ASSERT_STREQ("A B", fields.at(0).c_str()); 293 294 tokenize("D \"A B\" C", ' ', '"', '"', &fields); 295 ASSERT_EQ(3ul, fields.size()); 296 ASSERT_STREQ("D", fields.at(0).c_str()); 297 ASSERT_STREQ("A B", fields.at(1).c_str()); 298 299 tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields); 300 ASSERT_EQ(4ul, fields.size()); 301 ASSERT_STREQ("D", fields.at(0).c_str()); 302 ASSERT_STREQ("A B", fields.at(1).c_str()); 303 ASSERT_STREQ("E F", fields.at(3).c_str()); 304 305 // No matching marks. 306 tokenize("D \"A B", ' ', '"', '"', &fields); 307 ASSERT_EQ(3ul, fields.size()); 308 ASSERT_STREQ("D", fields.at(0).c_str()); 309 ASSERT_STREQ("\"A", fields.at(1).c_str()); 310 311 tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields); 312 ASSERT_EQ(5ul, fields.size()); 313 ASSERT_STREQ("D", fields.at(0).c_str()); 314 ASSERT_STREQ("A B", fields.at(1).c_str()); 315 ASSERT_STREQ("E F", fields.at(3).c_str()); 316 } 317 318 // Tests counting substrings. 319 TEST(SplitTest, CountSubstrings) { 320 std::vector<std::string> fields; 321 322 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields)); 323 fields.clear(); 324 EXPECT_EQ(1ul, split("one", ',', &fields)); 325 326 // Empty fields between commas count. 327 fields.clear(); 328 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields)); 329 fields.clear(); 330 EXPECT_EQ(3ul, split(",three,", ',', &fields)); 331 fields.clear(); 332 EXPECT_EQ(1ul, split("", ',', &fields)); 333 } 334 335 // Tests comparing substrings. 336 TEST(SplitTest, CompareSubstrings) { 337 std::vector<std::string> fields; 338 339 split("find,middle,one", ',', &fields); 340 ASSERT_EQ(3ul, fields.size()); 341 ASSERT_STREQ("middle", fields.at(1).c_str()); 342 fields.clear(); 343 344 // Empty fields between commas count. 345 split("find,,middle,one", ',', &fields); 346 ASSERT_EQ(4ul, fields.size()); 347 ASSERT_STREQ("middle", fields.at(2).c_str()); 348 fields.clear(); 349 split("", ',', &fields); 350 ASSERT_EQ(1ul, fields.size()); 351 ASSERT_STREQ("", fields.at(0).c_str()); 352 } 353 354 TEST(BoolTest, DecodeValid) { 355 bool value; 356 EXPECT_TRUE(FromString("true", &value)); 357 EXPECT_TRUE(value); 358 EXPECT_TRUE(FromString("true,", &value)); 359 EXPECT_TRUE(value); 360 EXPECT_TRUE(FromString("true , true", &value)); 361 EXPECT_TRUE(value); 362 EXPECT_TRUE(FromString("true ,\n false", &value)); 363 EXPECT_TRUE(value); 364 EXPECT_TRUE(FromString(" true \n", &value)); 365 EXPECT_TRUE(value); 366 367 EXPECT_TRUE(FromString("false", &value)); 368 EXPECT_FALSE(value); 369 EXPECT_TRUE(FromString(" false ", &value)); 370 EXPECT_FALSE(value); 371 EXPECT_TRUE(FromString(" false, ", &value)); 372 EXPECT_FALSE(value); 373 374 EXPECT_TRUE(FromString<bool>("true\n")); 375 EXPECT_FALSE(FromString<bool>("false\n")); 376 } 377 378 TEST(BoolTest, DecodeInvalid) { 379 bool value; 380 EXPECT_FALSE(FromString("True", &value)); 381 EXPECT_FALSE(FromString("TRUE", &value)); 382 EXPECT_FALSE(FromString("False", &value)); 383 EXPECT_FALSE(FromString("FALSE", &value)); 384 EXPECT_FALSE(FromString("0", &value)); 385 EXPECT_FALSE(FromString("1", &value)); 386 EXPECT_FALSE(FromString("0,", &value)); 387 EXPECT_FALSE(FromString("1,", &value)); 388 EXPECT_FALSE(FromString("1,0", &value)); 389 EXPECT_FALSE(FromString("1.", &value)); 390 EXPECT_FALSE(FromString("1.0", &value)); 391 EXPECT_FALSE(FromString("", &value)); 392 EXPECT_FALSE(FromString<bool>("false\nfalse")); 393 } 394 395 TEST(BoolTest, RoundTrip) { 396 bool value; 397 EXPECT_TRUE(FromString(ToString(true), &value)); 398 EXPECT_TRUE(value); 399 EXPECT_TRUE(FromString(ToString(false), &value)); 400 EXPECT_FALSE(value); 401 } 402 } // namespace talk_base 403