xref: /trunk/main/sal/qa/rtl/oustring/rtl_ustr.cxx (revision f0853378f1a90e669189f0f58595ee993d034643)
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