1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 25 // MARKER(update_precomp.py): autogen include statement, do not remove 26 #include "precompiled_sal.hxx" 27 #include "gtest/gtest.h" 28 #include <rtl/ustring.hxx> 29 30 /** print a UNI_CODE file name. 31 */ 32 inline void printOUString( ::rtl::OUString const & _suStr ) 33 { 34 rtl::OString aString; 35 36 printf( "OUString: " ); 37 aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US ); 38 printf( "%s\n", aString.getStr( ) ); 39 } 40 41 42 namespace rtl_ustr 43 { 44 45 class compare : public ::testing::Test 46 { 47 public: 48 }; // class compare 49 50 TEST_F(compare, compare_000) 51 { 52 // Former test passed (NULL, NULL); the "should not GPF" comment was 53 // wrong -- rtl_ustr_compare requires null-terminated strings and 54 // unconditionally dereferences both, so NULL is undefined behaviour. 55 // Verify the ordering-sign contract instead, which had no coverage. 56 rtl::OUString aStr1 = rtl::OUString::createFromAscii("abc"); 57 rtl::OUString aStr2 = rtl::OUString::createFromAscii("abd"); 58 59 ASSERT_TRUE(rtl_ustr_compare( aStr1.getStr(), aStr2.getStr()) < 0) 60 << "\"abc\" must compare less than \"abd\"."; 61 ASSERT_TRUE(rtl_ustr_compare( aStr2.getStr(), aStr1.getStr()) > 0) 62 << "\"abd\" must compare greater than \"abc\"."; 63 } 64 65 TEST_F(compare, compare_000_1) 66 { 67 // Former test passed (validStr, NULL) -> undefined behaviour. 68 // Verify the empty-string boundary instead. 69 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 70 rtl::OUString aEmpty; 71 72 ASSERT_TRUE(rtl_ustr_compare( aStr1.getStr(), aEmpty.getStr()) > 0) 73 << "a non-empty string must be greater than the empty string."; 74 ASSERT_TRUE(rtl_ustr_compare( aEmpty.getStr(), aStr1.getStr()) < 0) 75 << "the empty string must be less than a non-empty string."; 76 } 77 TEST_F(compare, compare_001) 78 { 79 rtl::OUString aStr1; 80 rtl::OUString aStr2; 81 82 sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr()); 83 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 84 } 85 86 TEST_F(compare, compare_002) 87 { 88 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 89 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line must be equal."); 90 91 sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr()); 92 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 93 } 94 95 TEST_F(compare, compare_003) 96 { 97 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must differ."); 98 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line foo bar, ok, differ."); 99 100 sal_Int32 nValue = rtl_ustr_compare( aStr1.getStr(), aStr2.getStr()); 101 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 102 } 103 104 class compareIgnoreAsciiCase : public ::testing::Test 105 { 106 public: 107 }; // class compareIgnoreAsciiCase 108 109 TEST_F(compareIgnoreAsciiCase, compare_000) 110 { 111 // Former test passed (NULL, NULL) -> undefined behaviour. Verify the 112 // case-insensitive ordering-sign contract instead. 113 rtl::OUString aStr1 = rtl::OUString::createFromAscii("abc"); 114 rtl::OUString aStr2 = rtl::OUString::createFromAscii("ABD"); 115 116 ASSERT_TRUE(rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr()) < 0) 117 << "\"abc\" must compare less than \"ABD\" ignoring case."; 118 ASSERT_TRUE(rtl_ustr_compareIgnoreAsciiCase( aStr2.getStr(), aStr1.getStr()) > 0) 119 << "\"ABD\" must compare greater than \"abc\" ignoring case."; 120 } 121 122 TEST_F(compareIgnoreAsciiCase, compare_000_1) 123 { 124 // Former test passed (validStr, NULL) -> undefined behaviour. 125 // Verify the empty-string boundary instead. 126 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 127 rtl::OUString aEmpty; 128 129 ASSERT_TRUE(rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aEmpty.getStr()) > 0) 130 << "a non-empty string must be greater than the empty string."; 131 } 132 TEST_F(compareIgnoreAsciiCase, compare_001) 133 { 134 rtl::OUString aStr1; 135 rtl::OUString aStr2; 136 137 sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr()); 138 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 139 } 140 141 TEST_F(compareIgnoreAsciiCase, compare_002) 142 { 143 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 144 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line must be equal."); 145 146 sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr()); 147 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 148 } 149 150 TEST_F(compareIgnoreAsciiCase, compare_002_1) 151 { 152 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 153 rtl::OUString aStr2 = rtl::OUString::createFromAscii("LINE MUST BE EQUAL."); 154 155 sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr()); 156 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal (if case insensitive)."; 157 } 158 159 TEST_F(compareIgnoreAsciiCase, compare_003) 160 { 161 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must differ."); 162 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line foo bar, ok, differ."); 163 164 sal_Int32 nValue = rtl_ustr_compareIgnoreAsciiCase( aStr1.getStr(), aStr2.getStr()); 165 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 166 } 167 // ----------------------------------------------------------------------------- 168 169 class shortenedCompareIgnoreAsciiCase_WithLength : public ::testing::Test 170 { 171 public: 172 }; // class compare 173 174 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_000) 175 { 176 // Length-bounded: NULL data with length 0 is well-defined (the loop 177 // body never runs) and must return 0. Keep NULL+0 as a regression 178 // guard, but assert it. 179 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( NULL, 0, NULL, 0, 0); 180 ASSERT_TRUE(nValue == 0) << "zero-length comparison must return 0, even for NULL data."; 181 } 182 183 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_000_1) 184 { 185 // First string has data, second is a zero-length string (NULL data, len 0). 186 // Nothing is dereferenced; the function returns the length difference. 187 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 188 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), NULL, 0, 1); 189 ASSERT_TRUE(nValue == aStr1.getLength()) 190 << "comparing against a zero-length string must yield the length difference."; 191 } 192 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_001) 193 { 194 rtl::OUString aStr1; 195 rtl::OUString aStr2; 196 197 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), aStr2.getStr(), aStr2.getLength(), aStr1.getLength()); 198 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 199 } 200 201 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_002) 202 { 203 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 204 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line must be equal."); 205 206 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), 207 aStr2.getStr(), aStr2.getLength(), 208 aStr1.getLength()); 209 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 210 } 211 212 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_002_1) 213 { 214 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 215 rtl::OUString aStr2 = rtl::OUString::createFromAscii("LINE MUST BE EQUAL."); 216 217 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), 218 aStr2.getStr(), aStr2.getLength(), 219 aStr1.getLength()); 220 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal (if case insensitive)."; 221 } 222 223 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_003) 224 { 225 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must differ."); 226 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line foo bar, ok, differ."); 227 228 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), 229 aStr2.getStr(), aStr2.getLength(), 230 5); 231 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal first 5 characters."; 232 } 233 234 TEST_F(shortenedCompareIgnoreAsciiCase_WithLength, compare_004) 235 { 236 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must differ."); 237 rtl::OUString aStr2 = rtl::OUString::createFromAscii("Line foo bar, ok, differ."); 238 239 sal_Int32 nValue = rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), 240 aStr2.getStr(), aStr2.getLength(), 241 aStr1.getLength()); 242 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 243 } 244 245 // // ----------------------------------------------------------------------------- 246 // 247 // class hashCode : public ::testing::Test 248 // { 249 // public: 250 // }; 251 // 252 // TEST_F(hashCode, hashCode_000) 253 // { 254 // sal_Int32 nHashCode = rtl_ustr_hashCode( NULL ); 255 // volatile int dummy = 0; 256 // } 257 // 258 // TEST_F(hashCode, hashCode_001) 259 // { 260 // rtl::OString aStr1 = "Line for a hashCode."; 261 // sal_Int32 nHashCode = rtl_ustr_hashCode( aStr1.getStr() ); 262 // printf("hashcode: %d\n", nHashCode); 263 // // ASSERT_TRUE(nValue == 0) << "failed."; 264 // } 265 // 266 // TEST_F(hashCode, hashCode_002) 267 // { 268 // rtl::OString aStr1 = "Line for a hashCode."; 269 // sal_Int32 nHashCode1 = rtl_ustr_hashCode( aStr1.getStr() ); 270 // 271 // rtl::OString aStr2 = "Line for a hashCode."; 272 // sal_Int32 nHashCode2 = rtl_ustr_hashCode( aStr2.getStr() ); 273 // 274 // ASSERT_TRUE(nHashCode1 == nHashCode2) << "hashcodes must be equal."; 275 // } 276 // 277 // TEST_F(hashCode, hashCode_003) 278 // { 279 // rtl::OString aStr1 = "Line for a hashCode."; 280 // sal_Int32 nHashCode1 = rtl_ustr_hashCode( aStr1.getStr() ); 281 // 282 // rtl::OString aStr2 = "Line for an other hashcode."; 283 // sal_Int32 nHashCode2 = rtl_ustr_hashCode( aStr2.getStr() ); 284 // 285 // ASSERT_TRUE(nHashCode1 != nHashCode2) << "hashcodes must differ."; 286 // } 287 // 288 // 289 // // ----------------------------------------------------------------------------- 290 // 291 class indexOfChar : public ::testing::Test 292 { 293 public: 294 }; // class indexOfChar 295 296 TEST_F(indexOfChar, indexOfChar_000) 297 { 298 // Former test passed NULL -> while(*pStr) dereferences NULL (UB). 299 // Verify the empty-string boundary: nothing is ever found -> -1. 300 rtl::OUString aStr1; 301 sal_Int32 nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'x' ); 302 ASSERT_TRUE(nIndex == -1) << "searching an empty string must return -1."; 303 } 304 305 TEST_F(indexOfChar, indexOfChar_001) 306 { 307 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a indexOfChar."); 308 309 sal_Int32 nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'L' ); 310 ASSERT_TRUE(nIndex == 0) << "index is wrong."; 311 312 /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'i' ); 313 ASSERT_TRUE(nIndex == 1) << "index is wrong."; 314 315 /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'n' ); 316 ASSERT_TRUE(nIndex == 2) << "index is wrong."; 317 318 /* sal_Int32 */ nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'e' ); 319 ASSERT_TRUE(nIndex == 3) << "index is wrong."; 320 } 321 322 TEST_F(indexOfChar, indexOfChar_002) 323 { 324 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a indexOfChar."); 325 sal_Int32 nIndex = rtl_ustr_indexOfChar( aStr1.getStr(), 'y' ); 326 327 ASSERT_TRUE(nIndex == -1) << "index is wrong."; 328 } 329 330 // // ----------------------------------------------------------------------------- 331 class lastIndexOfChar : public ::testing::Test 332 { 333 public: 334 }; // class lastIndexOfChar 335 336 TEST_F(lastIndexOfChar, lastIndexOfChar_000) 337 { 338 // Former test passed NULL -> getLength(NULL) dereferences NULL (UB). 339 // Verify the empty-string boundary instead. 340 rtl::OUString aStr1; 341 sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'x' ); 342 ASSERT_TRUE(nIndex == -1) << "searching an empty string must return -1."; 343 } 344 345 TEST_F(lastIndexOfChar, lastIndexOfChar_001) 346 { 347 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfChar."); 348 349 sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'C' ); 350 ASSERT_TRUE(nIndex == 22) << "index is wrong."; 351 352 /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'h' ); 353 ASSERT_TRUE(nIndex == 23) << "index is wrong."; 354 355 /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'a' ); 356 ASSERT_TRUE(nIndex == 24) << "index is wrong."; 357 358 /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'r' ); 359 ASSERT_TRUE(nIndex == 25) << "index is wrong."; 360 } 361 362 TEST_F(lastIndexOfChar, lastIndexOfChar_002) 363 { 364 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfChar."); 365 sal_Int32 nIndex = rtl_ustr_lastIndexOfChar( aStr1.getStr(), 'y' ); 366 367 ASSERT_TRUE(nIndex == -1) << "index is wrong."; 368 } 369 370 // ----------------------------------------------------------------------------- 371 372 class indexOfStr : public ::testing::Test 373 { 374 public: 375 }; // class compare 376 377 TEST_F(indexOfStr, indexOfStr_000) 378 { 379 // Former test passed (NULL, NULL) -> getLength(NULL) dereferences NULL (UB). 380 // Verify the empty-haystack boundary: nothing is found -> -1. 381 rtl::OUString aStr1; 382 rtl::OUString suSearch = rtl::OUString::createFromAscii("x"); 383 sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 384 ASSERT_TRUE(nIndex == -1) << "searching in an empty string must return -1."; 385 } 386 387 TEST_F(indexOfStr, indexOfStr_000_1) 388 { 389 // Former test passed a NULL needle -> getLength(NULL) (UB). 390 // Verify the empty-needle boundary: an empty search string is never found. 391 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a indexOfStr."); 392 rtl::OUString suSearch; 393 sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 394 ASSERT_TRUE(nIndex == -1) << "an empty search string is never found -> -1."; 395 } 396 397 TEST_F(indexOfStr, indexOfStr_001) 398 { 399 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a indexOfStr."); 400 401 rtl::OUString suSearch = rtl::OUString::createFromAscii("Line"); 402 sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 403 ASSERT_TRUE(nIndex == 0) << "index is wrong."; 404 405 /* rtl::OUString */ suSearch = rtl::OUString::createFromAscii("for"); 406 /* sal_Int32 */ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 407 ASSERT_TRUE(nIndex == 5) << "index is wrong."; 408 409 /* rtl::OUString */ suSearch = rtl::OUString::createFromAscii("a"); 410 /* sal_Int32 */ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 411 ASSERT_TRUE(nIndex == 9) << "index is wrong."; 412 413 /* rtl::OUString */ suSearch = rtl::OUString::createFromAscii("a index"); 414 /* sal_Int32 */ nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 415 ASSERT_TRUE(nIndex ==9) << "index is wrong."; 416 } 417 418 TEST_F(indexOfStr, indexOfStr_002) 419 { 420 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a indexOfStr."); 421 rtl::OUString suSearch = rtl::OUString::createFromAscii("not exist"); 422 sal_Int32 nIndex = rtl_ustr_indexOfStr( aStr1.getStr(), suSearch.getStr() ); 423 424 ASSERT_TRUE(nIndex == -1) << "index is wrong."; 425 } 426 427 // ----------------------------------------------------------------------------- 428 429 430 class lastIndexOfStr : public ::testing::Test 431 { 432 public: 433 }; // class lastIndexOfStr 434 435 TEST_F(lastIndexOfStr, lastIndexOfStr_000) 436 { 437 // Former test passed (NULL, NULL) -> getLength(NULL) dereferences NULL (UB). 438 // Verify the empty-haystack boundary instead. 439 rtl::OUString aStr1; 440 rtl::OUString aSearchStr = rtl::OUString::createFromAscii("Line"); 441 sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 442 ASSERT_TRUE(nIndex == -1) << "searching in an empty string must return -1."; 443 } 444 445 TEST_F(lastIndexOfStr, lastIndexOfStr_000_1) 446 { 447 // Former test passed a NULL needle -> getLength(NULL) (UB). 448 // Verify the empty-needle boundary: an empty search string is never found. 449 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfStr."); 450 rtl::OUString aSearchStr; 451 sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 452 ASSERT_TRUE(nIndex == -1) << "an empty search string is never found -> -1."; 453 } 454 455 TEST_F(lastIndexOfStr, lastIndexOfStr_001) 456 { 457 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfStr."); 458 rtl::OUString aSearchStr = rtl::OUString::createFromAscii("Index"); 459 460 sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 461 ASSERT_TRUE(nIndex == 15) << "index is wrong."; 462 463 /* rtl::OString */ aSearchStr = rtl::OUString::createFromAscii("Line"); 464 /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 465 ASSERT_TRUE(nIndex == 0) << "index is wrong."; 466 467 /* rtl::OString */ aSearchStr = rtl::OUString::createFromAscii(""); 468 /* sal_Int32 */ nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 469 ASSERT_TRUE(nIndex == -1) << "index is wrong."; 470 } 471 472 TEST_F(lastIndexOfStr, lastIndexOfStr_002) 473 { 474 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfStr."); 475 rtl::OUString aSearchStr = rtl::OUString::createFromAscii("foo"); 476 sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 477 478 ASSERT_TRUE(nIndex == -1) << "index is wrong."; 479 } 480 481 TEST_F(lastIndexOfStr, lastIndexOfStr_003) 482 { 483 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line for a lastIndexOfStr."); 484 rtl::OUString aSearchStr = rtl::OUString::createFromAscii("O"); 485 sal_Int32 nIndex = rtl_ustr_lastIndexOfStr( aStr1.getStr(), aSearchStr.getStr() ); 486 487 ASSERT_TRUE(nIndex == 20) << "index is wrong."; 488 } 489 490 // ----------------------------------------------------------------------------- 491 492 class replaceChar : public ::testing::Test 493 { 494 public: 495 }; // class replaceChar 496 497 TEST_F(replaceChar, replaceChar_000) 498 { 499 // Former test passed NULL -> while(*pStr) dereferences NULL (UB). 500 // Verify the empty-string boundary: replacing in "" is a no-op. 501 sal_Unicode pStr[] = { 0 }; 502 rtl_ustr_replaceChar( pStr, 'a', 'b' ); 503 ASSERT_TRUE(pStr[0] == 0) << "replacing in an empty string must leave it empty."; 504 } 505 506 TEST_F(replaceChar, replaceChar_001) 507 { 508 rtl::OUString aStr1 = rtl::OUString::createFromAscii("replace char."); 509 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("ruplacu char."); 510 511 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 512 sal_Unicode* pStr = (sal_Unicode*) malloc( nLength + sizeof(sal_Unicode)); // length + 1 (null terminator) 513 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 514 memset(pStr, 0, nLength + sizeof(sal_Unicode)); 515 memcpy(pStr, aStr1.getStr(), nLength); 516 517 rtl_ustr_replaceChar( pStr, 'e', 'u' ); 518 rtl::OUString suStr(pStr, aStr1.getLength()); 519 520 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "replace failed"; 521 free(pStr); 522 } 523 524 // ----------------------------------------------------------------------------- 525 526 class replaceChar_WithLength : public ::testing::Test 527 { 528 public: 529 }; // class replaceChar 530 531 TEST_F(replaceChar_WithLength, replaceChar_WithLength_000) 532 { 533 // Length-bounded: NULL data with length 0 never dereferences -> no-op. 534 rtl_ustr_replaceChar_WithLength( NULL, 0, 0, 0 ); 535 SUCCEED() << "NULL data with zero length must be tolerated (no dereference)."; 536 } 537 538 TEST_F(replaceChar_WithLength, replaceChar_WithLength_000_1) 539 { 540 // Former test passed (NULL, 1, ...) -> the loop runs once and 541 // dereferences NULL (UB). Verify the length bound instead: only the 542 // first nLen characters are touched, the rest are left intact. 543 sal_Unicode pStr[] = { 'a', 'a', 'a', 'a', 0 }; 544 sal_Unicode pExpected[] = { 'b', 'b', 'a', 'a', 0 }; 545 rtl_ustr_replaceChar_WithLength( pStr, 2, 'a', 'b' ); 546 ASSERT_TRUE(rtl::OUString(pStr).equals(rtl::OUString(pExpected)) == sal_True) 547 << "only the first nLen characters must be replaced."; 548 } 549 TEST_F(replaceChar_WithLength, replaceChar_WithLength_001) 550 { 551 rtl::OUString aStr1 = rtl::OUString::createFromAscii("replace char."); 552 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("ruplace char."); 553 554 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 555 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength); 556 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 557 memcpy(pStr, aStr1.getStr(), nLength); 558 559 rtl_ustr_replaceChar_WithLength( pStr, 6, 'e', 'u' ); 560 rtl::OUString suStr(pStr, aStr1.getLength()); 561 562 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "replace failed"; 563 free(pStr); 564 } 565 566 TEST_F(replaceChar_WithLength, replaceChar_WithLength_002) 567 { 568 rtl::OUString aStr1 = rtl::OUString::createFromAscii("eeeeeeeeeeeee"); 569 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("uuuuuueeeeeee"); 570 571 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 572 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength); // no null terminator is need 573 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 574 memcpy(pStr, aStr1.getStr(), nLength); 575 576 rtl_ustr_replaceChar_WithLength( pStr, 6, 'e', 'u' ); 577 rtl::OUString suStr(pStr, aStr1.getLength()); 578 579 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "replace failed"; 580 free(pStr); 581 } 582 583 // ----------------------------------------------------------------------------- 584 585 class toAsciiLowerCase : public ::testing::Test 586 { 587 public: 588 }; // class replaceChar 589 590 TEST_F(toAsciiLowerCase, toAsciiLowerCase_000) 591 { 592 // Former test passed NULL -> while(*pStr) dereferences NULL (UB). 593 // Verify the empty-string boundary: lowercasing "" is a no-op. 594 sal_Unicode pStr[] = { 0 }; 595 rtl_ustr_toAsciiLowerCase( pStr ); 596 ASSERT_TRUE(pStr[0] == 0) << "lowercasing an empty string must leave it empty."; 597 } 598 599 TEST_F(toAsciiLowerCase, toAsciiLowerCase_001) 600 { 601 rtl::OUString aStr1 = rtl::OUString::createFromAscii("CHANGE THIS TO ASCII LOWER CASE."); 602 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("change this to ascii lower case."); 603 604 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 605 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength + sizeof(sal_Unicode) ); // we need to add '\0' so one more 606 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 607 memset(pStr, 0, nLength + sizeof(sal_Unicode)); // empty the sal_Unicode array 608 memcpy(pStr, aStr1.getStr(), nLength); 609 610 rtl_ustr_toAsciiLowerCase( pStr ); 611 rtl::OUString suStr(pStr, aStr1.getLength()); 612 613 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "failed"; 614 free(pStr); 615 } 616 617 class toAsciiLowerCase_WithLength : public ::testing::Test 618 { 619 }; // class replaceChar 620 621 TEST_F(toAsciiLowerCase, toAsciiLowerCase_WithLength_000) 622 { 623 // Length-bounded: NULL data with length 0 never dereferences -> no-op. 624 rtl_ustr_toAsciiLowerCase_WithLength( NULL, 0 ); 625 SUCCEED() << "NULL data with zero length must be tolerated (no dereference)."; 626 } 627 628 TEST_F(toAsciiLowerCase, toAsciiLowerCase_WithLength_001) 629 { 630 rtl::OUString aStr1 = rtl::OUString::createFromAscii("CHANGE THIS TO ASCII LOWER CASE."); 631 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("change thiS TO ASCII LOWER CASE."); 632 633 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 634 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength); 635 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 636 memcpy(pStr, aStr1.getStr(), nLength); 637 638 rtl_ustr_toAsciiLowerCase_WithLength( pStr, 10 ); 639 640 rtl::OUString suStr(pStr, aStr1.getLength()); 641 sal_Bool bResult = aShouldStr1.equals(suStr); 642 643 printOUString(suStr); 644 printf("Result length: %d\n", suStr.getLength() ); 645 printf("Result: %d\n", bResult); 646 647 ASSERT_TRUE(bResult == sal_True) << "failed"; 648 free(pStr); 649 } 650 651 // ----------------------------------------------------------------------------- 652 653 class toAsciiUpperCase : public ::testing::Test 654 { 655 public: 656 }; // class replaceChar 657 658 TEST_F(toAsciiUpperCase, toAsciiUpperCase_000) 659 { 660 // Former test passed NULL -> while(*pStr) dereferences NULL (UB). 661 // Verify the empty-string boundary: uppercasing "" is a no-op. 662 sal_Unicode pStr[] = { 0 }; 663 rtl_ustr_toAsciiUpperCase( pStr ); 664 ASSERT_TRUE(pStr[0] == 0) << "uppercasing an empty string must leave it empty."; 665 } 666 667 TEST_F(toAsciiUpperCase, toAsciiUpperCase_001) 668 { 669 rtl::OUString aStr1 = rtl::OUString::createFromAscii("change this to ascii upper case."); 670 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("CHANGE THIS TO ASCII UPPER CASE."); 671 672 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 673 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength + sizeof(sal_Unicode)); // length + null terminator 674 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 675 memset(pStr, 0, nLength + sizeof(sal_Unicode)); 676 memcpy(pStr, aStr1.getStr(), nLength); 677 678 rtl_ustr_toAsciiUpperCase( pStr ); 679 rtl::OUString suStr(pStr, aStr1.getLength()); 680 681 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "failed"; 682 free(pStr); 683 } 684 685 class toAsciiUpperCase_WithLength : public ::testing::Test 686 { 687 public: 688 }; // class replaceChar 689 690 TEST_F(toAsciiUpperCase_WithLength, toAsciiUpperCase_WithLength_000) 691 { 692 // Length-bounded: NULL data with length 0 never dereferences -> no-op. 693 rtl_ustr_toAsciiUpperCase_WithLength( NULL, 0 ); 694 SUCCEED() << "NULL data with zero length must be tolerated (no dereference)."; 695 } 696 697 TEST_F(toAsciiUpperCase_WithLength, toAsciiUpperCase_WithLength_001) 698 { 699 rtl::OUString aStr1 = rtl::OUString::createFromAscii("change this to ascii lower case."); 700 rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("CHANGE THIs to ascii lower case."); 701 702 sal_uInt32 nLength = aStr1.getLength() * sizeof(sal_Unicode); 703 sal_Unicode* pStr = (sal_Unicode*) malloc(nLength); 704 ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 705 706 memcpy(pStr, aStr1.getStr(), nLength); 707 rtl_ustr_toAsciiUpperCase_WithLength( pStr, 10 ); 708 rtl::OUString suStr(pStr, aStr1.getLength()); 709 710 // printf("Uppercase with length: '%s'\n", aStr1.getStr()); 711 ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "failed"; 712 free(pStr); 713 } 714 715 // ----------------------------------------------------------------------------- 716 717 class trim_WithLength : public ::testing::Test 718 { 719 public: 720 }; 721 722 TEST_F(trim_WithLength, trim_WithLength_000) 723 { 724 // Length-bounded: NULL data with length 0 never dereferences and 725 // returns the resulting length 0. 726 sal_Int32 nLen = rtl_ustr_trim_WithLength(NULL, 0); 727 ASSERT_TRUE(nLen == 0) << "trimming a zero-length string must return 0 (and not GPF)."; 728 } 729 730 TEST_F(trim_WithLength, trim_WithLength_000_1) 731 { 732 rtl::OUString suStr = rtl::OUString::createFromAscii(" trim this"); 733 734 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 735 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 736 memcpy(pStr, suStr.getStr(), nLength); 737 738 rtl_ustr_trim_WithLength( pStr, 0 ); 739 free(pStr); 740 } 741 742 TEST_F(trim_WithLength, trim_WithLength_001) 743 { 744 rtl::OUString suStr = rtl::OUString::createFromAscii(" trim this"); 745 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 746 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 747 memcpy(pStr, suStr.getStr(), nLength); 748 749 rtl_ustr_trim_WithLength( pStr, 2 ); 750 751 ASSERT_TRUE(rtl::OUString(pStr).getLength() == 0) << "string should be empty"; 752 free(pStr); 753 } 754 755 756 TEST_F(trim_WithLength, trim_WithLength_002) 757 { 758 rtl::OUString suStr = rtl::OUString::createFromAscii("trim this"); 759 760 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 761 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 762 memcpy(pStr, suStr.getStr(), nLength); 763 764 rtl_ustr_trim_WithLength( pStr, 5 ); 765 766 ASSERT_TRUE(rtl::OUString(pStr).getLength() == 4) << "string should contain 'trim'"; 767 free(pStr); 768 } 769 770 771 TEST_F(trim_WithLength, trim_WithLength_003) 772 { 773 rtl::OUString suStr = rtl::OUString::createFromAscii(" trim this"); 774 775 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 776 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 777 memcpy(pStr, suStr.getStr(), nLength); 778 779 rtl_ustr_trim_WithLength( pStr, 11 ); 780 781 ASSERT_TRUE(rtl::OUString(pStr).getLength() == 4) << "string should contain 'trim'"; 782 free(pStr); 783 } 784 785 TEST_F(trim_WithLength, trim_WithLength_004) 786 { 787 rtl::OUString suStr = rtl::OUString::createFromAscii("\r\n\t \n\r trim \n this"); 788 789 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 790 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 791 memcpy(pStr, suStr.getStr(), nLength); 792 793 rtl_ustr_trim_WithLength( pStr, 17 ); 794 795 ASSERT_TRUE(rtl::OUString(pStr).getLength() == 4) << "string should contain 'trim'"; 796 free(pStr); 797 } 798 799 TEST_F(trim_WithLength, trim_WithLength_005) 800 { 801 rtl::OUString suStr = rtl::OUString::createFromAscii("\r\n\t \n\r trim \t this \n\r\t\t "); 802 803 sal_uInt32 nLength = suStr.getLength() * sizeof(sal_Unicode); 804 sal_Unicode *pStr = (sal_Unicode*)malloc(nLength); 805 memcpy(pStr, suStr.getStr(), nLength); 806 807 rtl_ustr_trim_WithLength( pStr, suStr.getLength() ); 808 809 ASSERT_TRUE(rtl::OUString(pStr).getLength() == 11) << "string should contain 'trim \\t this'"; 810 free(pStr); 811 } 812 813 // ----------------------------------------------------------------------------- 814 815 class valueOfChar : public ::testing::Test 816 { 817 public: 818 }; 819 820 TEST_F(valueOfChar, valueOfChar_000) 821 { 822 // Former test passed NULL -> the function writes through NULL (UB); 823 // the "should not GPF" comment was wrong, it always did. 824 // Verify the documented behaviour on a real buffer. 825 sal_Unicode pStr[RTL_USTR_MAX_VALUEOFCHAR]; 826 sal_Int32 nLen = rtl_ustr_valueOfChar(pStr, 'Z'); 827 ASSERT_TRUE(nLen == 1) << "valueOfChar must return 1."; 828 ASSERT_TRUE(pStr[0] == L'Z') << "valueOfChar must write the character."; 829 ASSERT_TRUE(pStr[1] == 0) << "valueOfChar must NUL-terminate."; 830 } 831 TEST_F(valueOfChar, valueOfChar_001) 832 { 833 sal_Unicode *pStr = (sal_Unicode*)malloc(RTL_USTR_MAX_VALUEOFCHAR); 834 if (pStr) 835 { 836 rtl_ustr_valueOfChar(pStr, 'A'); 837 838 ASSERT_TRUE(pStr[0] == L'A') << "string should contain 'A'"; 839 free(pStr); 840 } 841 } 842 843 844 class ascii_compare_WithLength : public ::testing::Test 845 { 846 public: 847 }; 848 849 TEST_F(ascii_compare_WithLength, zero_length) 850 { 851 sal_Unicode pUnicode[] = {0xffff, 0xffff}; 852 char const * pAscii = "reference"; 853 854 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(pUnicode, 0, pAscii); 855 ASSERT_TRUE(value < 0) << "ref string is empty, compare failed, needs to be <0."; 856 } 857 858 TEST_F(ascii_compare_WithLength, equal_ascii_shorter) 859 { 860 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("referenceString")); 861 char const * pAscii = "reference"; 862 863 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii); 864 ASSERT_TRUE(value > 0) << "ref string is bigger, compare failed, needs to be >0."; 865 } 866 867 TEST_F(ascii_compare_WithLength, equal_ascii_shorter_asciiLength) 868 { 869 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("referenceString")); 870 char const * pAscii = "reference"; 871 872 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, rtl_str_getLength(pAscii), pAscii); 873 ASSERT_TRUE(value == 0) << "ref string is bigger despite ascii length, compare failed, needs to be == 0."; 874 } 875 876 TEST_F(ascii_compare_WithLength, equal_ref_shorter) 877 { 878 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("reference")); 879 char const * pAscii = "referenceString"; 880 881 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii); 882 ASSERT_TRUE(value < 0) << "ascii string is bigger, but only compared to ref length, needs to be 0."; 883 } 884 885 TEST_F(ascii_compare_WithLength, equal) 886 { 887 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("reference")); 888 char const * pAscii = "reference"; 889 890 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii); 891 ASSERT_TRUE(value == 0) << "strings are equal, compare failed, needs to be 0."; 892 } 893 894 TEST_F(ascii_compare_WithLength, unequal_reference_bigger) 895 { 896 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("defghi")); 897 char const * pAscii = "abc"; 898 899 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii); 900 ASSERT_TRUE(value > 0) << "strings are unequal and ref is bigger, needs to be >0."; 901 } 902 903 TEST_F(ascii_compare_WithLength, unequal_ascii_bigger) 904 { 905 rtl::OUString refStr(RTL_CONSTASCII_USTRINGPARAM("abc")); 906 char const * pAscii = "defghi"; 907 908 sal_Int32 value = rtl_ustr_ascii_compare_WithLength(refStr.pData->buffer, refStr.pData->length, pAscii); 909 910 ASSERT_TRUE(value < 0) << "strings are unequal and ascii is bigger, needs to be <0."; 911 } 912 913 914 class ascii_shortenedCompareIgnoreAsciiCase_WithLength : public ::testing::Test 915 { 916 public: 917 }; // class ascii_shortenedCompareIgnoreAsciiCase_WithLength 918 919 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_000) 920 { 921 // A shortened length of 0 means "compare nothing"; the loop never runs 922 // and the function returns 0 without dereferencing the (NULL) data. 923 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( NULL, 0, NULL, 0); 924 ASSERT_TRUE(nValue == 0) << "a shortened length of 0 must return 0, even for NULL data."; 925 } 926 927 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_1) 928 { 929 // Shortened length 0 -> return 0 without touching the NULL ascii string. 930 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 931 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), aStr1.getLength(), NULL, 0); 932 ASSERT_TRUE(nValue == 0) << "a shortened length of 0 must return 0."; 933 } 934 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_2) 935 { 936 // Shortened length 0 -> return 0, even though both strings have data. 937 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 938 rtl::OString sStr2 = "Line is shorter."; 939 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( aStr1.getStr(), sStr2.getLength(), sStr2.getStr(), 0); 940 ASSERT_TRUE(nValue == 0) << "a shortened length of 0 must return 0."; 941 } 942 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_001) 943 { 944 rtl::OUString suStr1; 945 rtl::OString sStr2; 946 947 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), 0, sStr2.getStr(), 0); 948 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 949 } 950 951 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_002) 952 { 953 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal."); 954 rtl::OString sStr2 = "Line must be equal."; 955 956 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr(), sStr2.getLength()); 957 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 958 } 959 960 TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength, ascii_shortenedCompareIgnoreAsciiCase_WithLength_003) 961 { 962 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must differ."); 963 rtl::OString sStr2 = "Line must be differ and longer."; 964 965 sal_Int32 nValue = rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr(), sStr2.getLength()); 966 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 967 } 968 969 // ----------------------------------------------------------------------------- 970 971 class ascii_compareIgnoreAsciiCase_WithLength : public ::testing::Test 972 { 973 public: 974 }; // class ascii_compareIgnoreAsciiCase_WithLength 975 976 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_000) 977 { 978 // Former test passed a NULL ascii string. Even with nStr1Len 0 this is 979 // undefined behaviour: the "!nStr1Len" branch returns "*pStr2 == '\0' ? 980 // 0 : -1", which dereferences the (NULL) ascii pointer. Use a valid 981 // (empty) ascii string instead: an empty-vs-empty comparison is 0. 982 rtl::OUString aEmpty; 983 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( aEmpty.getStr(), 0, ""); 984 ASSERT_TRUE(nValue == 0) << "comparing two empty strings must return 0."; 985 } 986 987 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_000_1) 988 { 989 // Former test passed (validStr, 0, NULL) -> the "!nStr1Len" branch 990 // dereferences the NULL ascii pointer. Verify the documented boundary 991 // instead: a zero-length first string vs. a non-empty ascii string is 992 // "less" (-1). 993 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 994 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( aStr1.getStr(), 0, "x"); 995 ASSERT_TRUE(nValue == -1) << "a zero-length string is less than a non-empty ascii string."; 996 } 997 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_000_2) 998 { 999 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1000 rtl::OString sStr2 = "Line is shorter."; 1001 rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( aStr1.getStr(), sStr2.getLength(), sStr2.getStr()); 1002 // should not GPF 1003 } 1004 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_001) 1005 { 1006 rtl::OUString suStr1; 1007 rtl::OString sStr2; 1008 1009 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), 0, sStr2.getStr()); 1010 ASSERT_TRUE(nValue == 0) << "compareIgnoreAsciiCase_WithLength failed, strings are equal."; 1011 } 1012 1013 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_002) 1014 { 1015 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1016 rtl::OString sStr2 = "Line must be equal."; 1017 1018 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr()); 1019 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1020 } 1021 1022 TEST_F(ascii_compareIgnoreAsciiCase_WithLength, ascii_compareIgnoreAsciiCase_WithLength_003) 1023 { 1024 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must differ."); 1025 rtl::OString sStr2 = "Line must be differ and longer."; 1026 1027 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( suStr1.getStr(), suStr1.getLength(), sStr2.getStr()); 1028 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 1029 } 1030 // ----------------------------------------------------------------------------- 1031 1032 class ascii_compare : public ::testing::Test 1033 { 1034 public: 1035 }; // class ascii_compare 1036 1037 TEST_F(ascii_compare, ascii_compare_000) 1038 { 1039 // Former test passed (NULL, NULL); the "should not GPF" comment was 1040 // wrong -- rtl_ustr_ascii_compare unconditionally dereferences both 1041 // pointers. Verify the ordering-sign contract instead. 1042 rtl::OUString aStr1 = rtl::OUString::createFromAscii("abc"); 1043 1044 ASSERT_TRUE(rtl_ustr_ascii_compare( aStr1.getStr(), "abd") < 0) 1045 << "\"abc\" must compare less than \"abd\"."; 1046 ASSERT_TRUE(rtl_ustr_ascii_compare( aStr1.getStr(), "abb") > 0) 1047 << "\"abc\" must compare greater than \"abb\"."; 1048 } 1049 1050 TEST_F(ascii_compare, ascii_compare_000_1) 1051 { 1052 // Former test passed (validStr, NULL) -> undefined behaviour. 1053 // Verify the empty-string boundary instead. 1054 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1055 ASSERT_TRUE(rtl_ustr_ascii_compare( aStr1.getStr(), "") > 0) 1056 << "a non-empty string must be greater than the empty string."; 1057 } 1058 TEST_F(ascii_compare, ascii_compare_001) 1059 { 1060 rtl::OUString suStr1; 1061 rtl::OString sStr2; 1062 1063 sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr()); 1064 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1065 } 1066 1067 TEST_F(ascii_compare, ascii_compare_002) 1068 { 1069 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1070 rtl::OString sStr2 = "Line must be equal."; 1071 1072 sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr()); 1073 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1074 } 1075 1076 TEST_F(ascii_compare, ascii_compare_003) 1077 { 1078 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must differ."); 1079 rtl::OString sStr2 = "Line foo bar, ok, differ."; 1080 1081 sal_Int32 nValue = rtl_ustr_ascii_compare( suStr1.getStr(), sStr2.getStr()); 1082 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 1083 } 1084 1085 // ----------------------------------------------------------------------------- 1086 1087 class ascii_compareIgnoreAsciiCase : public ::testing::Test 1088 { 1089 public: 1090 }; // class ascii_compareIgnoreAsciiCase 1091 1092 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_000) 1093 { 1094 // Former test passed (NULL, NULL) -> undefined behaviour (both pointers 1095 // are dereferenced). Verify the case-insensitive ordering-sign contract. 1096 rtl::OUString aStr1 = rtl::OUString::createFromAscii("abc"); 1097 1098 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "ABD") < 0) 1099 << "\"abc\" must compare less than \"ABD\" ignoring case."; 1100 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "ABB") > 0) 1101 << "\"abc\" must compare greater than \"ABB\" ignoring case."; 1102 } 1103 1104 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_000_1) 1105 { 1106 // Former test passed (validStr, NULL) -> undefined behaviour. 1107 // Verify the empty-string boundary instead. 1108 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1109 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "") > 0) 1110 << "a non-empty string must be greater than the empty string."; 1111 } 1112 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_001) 1113 { 1114 rtl::OUString suStr1; 1115 rtl::OString sStr2; 1116 1117 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1118 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1119 } 1120 1121 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_002) 1122 { 1123 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1124 rtl::OString sStr2 = "Line must be equal."; 1125 1126 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1127 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1128 } 1129 1130 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_002_1) 1131 { 1132 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal, when ignore case."); 1133 rtl::OString sStr2 = "LINE MUST BE EQUAL, WHEN IGNORE CASE."; 1134 1135 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1136 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal (if case insensitive)."; 1137 } 1138 1139 TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_003) 1140 { 1141 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must differ."); 1142 rtl::OString sStr2 = "Line foo bar, ok, differ."; 1143 1144 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1145 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 1146 } 1147 1148 //! LLA: some more tests with some high level strings 1149 1150 // TEST_F(ascii_compareIgnoreAsciiCase, ascii_compareIgnoreAsciiCase_001() 1151 // { 1152 // rtl::OUString suStr1 = rtl::OUString::createFromAscii("change this to ascii upper case."); 1153 // rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("CHANGE THIS TO ASCII UPPER CASE."); 1154 // 1155 // sal_uInt32 nLength = suStr1.getLength() * sizeof(sal_Unicode); 1156 // sal_Unicode* pStr = (sal_Unicode*) malloc(nLength + sizeof(sal_Unicode)); // length + null terminator 1157 // ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 1158 // memset(pStr, 0, nLength + sizeof(sal_Unicode)); 1159 // memcpy(pStr, suStr1.getStr(), nLength); 1160 // 1161 // rtl_ustr_ascii_compareIgnoreAsciiCase( pStr ); 1162 // rtl::OUString suStr(pStr, suStr1.getLength()); 1163 // 1164 // ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "failed"; 1165 // free(pStr); 1166 // } 1167 1168 // sample out of inc/rtl/ustring.hxx 1169 // rtl_uString * pToken = NULL; 1170 // sal_Int32 nIndex = 0; 1171 // do 1172 // { 1173 // ... 1174 // nIndex = rtl_uString_getToken(&pToken, pStr, 0, ';', nIndex); 1175 // ... 1176 // } 1177 // while (nIndex >= 0); 1178 1179 class getToken : public ::testing::Test 1180 { 1181 public: 1182 }; // class ascii_compareIgnoreAsciiCase 1183 1184 TEST_F(getToken, getToken_000) 1185 { 1186 // Former test passed (NULL, NULL) -> undefined behaviour. Verify the 1187 // case-insensitive ordering-sign contract instead. 1188 rtl::OUString aStr1 = rtl::OUString::createFromAscii("abc"); 1189 1190 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "ABD") < 0) 1191 << "\"abc\" must compare less than \"ABD\" ignoring case."; 1192 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "ABB") > 0) 1193 << "\"abc\" must compare greater than \"ABB\" ignoring case."; 1194 } 1195 1196 TEST_F(getToken, ascii_compareIgnoreAsciiCase_000_1) 1197 { 1198 // Former test passed (validStr, NULL) -> undefined behaviour. 1199 // Verify the empty-string boundary instead. 1200 rtl::OUString aStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1201 ASSERT_TRUE(rtl_ustr_ascii_compareIgnoreAsciiCase( aStr1.getStr(), "") > 0) 1202 << "a non-empty string must be greater than the empty string."; 1203 } 1204 TEST_F(getToken, ascii_compareIgnoreAsciiCase_001) 1205 { 1206 rtl::OUString suStr1; 1207 rtl::OString sStr2; 1208 1209 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1210 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1211 } 1212 1213 TEST_F(getToken, ascii_compareIgnoreAsciiCase_002) 1214 { 1215 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal."); 1216 rtl::OString sStr2 = "Line must be equal."; 1217 1218 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1219 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal."; 1220 } 1221 1222 TEST_F(getToken, ascii_compareIgnoreAsciiCase_002_1) 1223 { 1224 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must be equal, when ignore case."); 1225 rtl::OString sStr2 = "LINE MUST BE EQUAL, WHEN IGNORE CASE."; 1226 1227 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1228 ASSERT_TRUE(nValue == 0) << "compare failed, strings are equal (if case insensitive)."; 1229 } 1230 1231 TEST_F(getToken, ascii_compareIgnoreAsciiCase_003) 1232 { 1233 rtl::OUString suStr1 = rtl::OUString::createFromAscii("Line must differ."); 1234 rtl::OString sStr2 = "Line foo bar, ok, differ."; 1235 1236 sal_Int32 nValue = rtl_ustr_ascii_compareIgnoreAsciiCase( suStr1.getStr(), sStr2.getStr()); 1237 ASSERT_TRUE(nValue != 0) << "compare failed, strings differ."; 1238 } 1239 1240 //! LLA: some more tests with some high level strings 1241 1242 // TEST_F(getToken, ascii_compareIgnoreAsciiCase_001) 1243 // { 1244 // rtl::OUString suStr1 = rtl::OUString::createFromAscii("change this to ascii upper case."); 1245 // rtl::OUString aShouldStr1 = rtl::OUString::createFromAscii("CHANGE THIS TO ASCII UPPER CASE."); 1246 // 1247 // sal_uInt32 nLength = suStr1.getLength() * sizeof(sal_Unicode); 1248 // sal_Unicode* pStr = (sal_Unicode*) malloc(nLength + sizeof(sal_Unicode)); // length + null terminator 1249 // ASSERT_TRUE(pStr != NULL) << "can't get memory for test"; 1250 // memset(pStr, 0, nLength + sizeof(sal_Unicode)); 1251 // memcpy(pStr, suStr1.getStr(), nLength); 1252 // 1253 // rtl_ustr_ascii_compareIgnoreAsciiCase( pStr ); 1254 // rtl::OUString suStr(pStr, suStr1.getLength()); 1255 // 1256 // ASSERT_TRUE(aShouldStr1.equals(suStr) == sal_True) << "failed"; 1257 // free(pStr); 1258 // } 1259 1260 } // namespace rtl_ustr 1261 1262 1263 int main(int argc, char **argv) 1264 { 1265 ::testing::InitGoogleTest(&argc, argv); 1266 return RUN_ALL_TESTS(); 1267 } 1268