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 */
printOUString(::rtl::OUString const & _suStr)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
TEST_F(compare,compare_000)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
TEST_F(compare,compare_000_1)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 }
TEST_F(compare,compare_001)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
TEST_F(compare,compare_002)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
TEST_F(compare,compare_003)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
TEST_F(compareIgnoreAsciiCase,compare_000)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
TEST_F(compareIgnoreAsciiCase,compare_000_1)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 }
TEST_F(compareIgnoreAsciiCase,compare_001)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
TEST_F(compareIgnoreAsciiCase,compare_002)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
TEST_F(compareIgnoreAsciiCase,compare_002_1)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
TEST_F(compareIgnoreAsciiCase,compare_003)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_000)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_000_1)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 }
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_001)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_002)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_002_1)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_003)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
TEST_F(shortenedCompareIgnoreAsciiCase_WithLength,compare_004)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
TEST_F(indexOfChar,indexOfChar_000)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
TEST_F(indexOfChar,indexOfChar_001)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
TEST_F(indexOfChar,indexOfChar_002)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
TEST_F(lastIndexOfChar,lastIndexOfChar_000)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
TEST_F(lastIndexOfChar,lastIndexOfChar_001)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
TEST_F(lastIndexOfChar,lastIndexOfChar_002)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
TEST_F(indexOfStr,indexOfStr_000)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
TEST_F(indexOfStr,indexOfStr_000_1)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
TEST_F(indexOfStr,indexOfStr_001)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
TEST_F(indexOfStr,indexOfStr_002)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
TEST_F(lastIndexOfStr,lastIndexOfStr_000)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
TEST_F(lastIndexOfStr,lastIndexOfStr_000_1)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
TEST_F(lastIndexOfStr,lastIndexOfStr_001)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
TEST_F(lastIndexOfStr,lastIndexOfStr_002)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
TEST_F(lastIndexOfStr,lastIndexOfStr_003)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
TEST_F(replaceChar,replaceChar_000)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
TEST_F(replaceChar,replaceChar_001)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
TEST_F(replaceChar_WithLength,replaceChar_WithLength_000)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
TEST_F(replaceChar_WithLength,replaceChar_WithLength_000_1)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 }
TEST_F(replaceChar_WithLength,replaceChar_WithLength_001)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
TEST_F(replaceChar_WithLength,replaceChar_WithLength_002)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
TEST_F(toAsciiLowerCase,toAsciiLowerCase_000)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
TEST_F(toAsciiLowerCase,toAsciiLowerCase_001)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
TEST_F(toAsciiLowerCase,toAsciiLowerCase_WithLength_000)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
TEST_F(toAsciiLowerCase,toAsciiLowerCase_WithLength_001)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
TEST_F(toAsciiUpperCase,toAsciiUpperCase_000)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
TEST_F(toAsciiUpperCase,toAsciiUpperCase_001)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
TEST_F(toAsciiUpperCase_WithLength,toAsciiUpperCase_WithLength_000)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
TEST_F(toAsciiUpperCase_WithLength,toAsciiUpperCase_WithLength_001)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
TEST_F(trim_WithLength,trim_WithLength_000)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
TEST_F(trim_WithLength,trim_WithLength_000_1)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
TEST_F(trim_WithLength,trim_WithLength_001)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
TEST_F(trim_WithLength,trim_WithLength_002)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
TEST_F(trim_WithLength,trim_WithLength_003)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
TEST_F(trim_WithLength,trim_WithLength_004)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
TEST_F(trim_WithLength,trim_WithLength_005)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
TEST_F(valueOfChar,valueOfChar_000)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 }
TEST_F(valueOfChar,valueOfChar_001)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
TEST_F(ascii_compare_WithLength,zero_length)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
TEST_F(ascii_compare_WithLength,equal_ascii_shorter)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
TEST_F(ascii_compare_WithLength,equal_ascii_shorter_asciiLength)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
TEST_F(ascii_compare_WithLength,equal_ref_shorter)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
TEST_F(ascii_compare_WithLength,equal)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
TEST_F(ascii_compare_WithLength,unequal_reference_bigger)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
TEST_F(ascii_compare_WithLength,unequal_ascii_bigger)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
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_000)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
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_1)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 }
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_000_2)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 }
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_001)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
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_002)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
TEST_F(ascii_shortenedCompareIgnoreAsciiCase_WithLength,ascii_shortenedCompareIgnoreAsciiCase_WithLength_003)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
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_000)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
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_000_1)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 }
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_000_2)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 }
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_001)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
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_002)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
TEST_F(ascii_compareIgnoreAsciiCase_WithLength,ascii_compareIgnoreAsciiCase_WithLength_003)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
TEST_F(ascii_compare,ascii_compare_000)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
TEST_F(ascii_compare,ascii_compare_000_1)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 }
TEST_F(ascii_compare,ascii_compare_001)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
TEST_F(ascii_compare,ascii_compare_002)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
TEST_F(ascii_compare,ascii_compare_003)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
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_000)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
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_000_1)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 }
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_001)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
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_002)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
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_002_1)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
TEST_F(ascii_compareIgnoreAsciiCase,ascii_compareIgnoreAsciiCase_003)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
TEST_F(getToken,getToken_000)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
TEST_F(getToken,ascii_compareIgnoreAsciiCase_000_1)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 }
TEST_F(getToken,ascii_compareIgnoreAsciiCase_001)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
TEST_F(getToken,ascii_compareIgnoreAsciiCase_002)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
TEST_F(getToken,ascii_compareIgnoreAsciiCase_002_1)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
TEST_F(getToken,ascii_compareIgnoreAsciiCase_003)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
main(int argc,char ** argv)1263 int main(int argc, char **argv)
1264 {
1265 ::testing::InitGoogleTest(&argc, argv);
1266 return RUN_ALL_TESTS();
1267 }
1268