Bug Summary

File:sal/rtl/source/string.cxx
Location:line 220, column 22
Description:Dereference of null pointer (loaded from variable 'pTarget')

Annotated Source Code

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 *
8 * OpenOffice.org - a multi-platform office productivity suite
9 *
10 * This file is part of OpenOffice.org.
11 *
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
15 *
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
21 *
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
26 *
27 ************************************************************************/
28
29#include "sal/config.h"
30
31#if defined(_MSC_VER) && (_MSC_VER >= 1400)
32#pragma warning(disable:4738) // storing 32-bit float result in memory, possible loss of performance
33#endif
34
35#include <cassert>
36#include <cstdlib>
37
38#include <rtl/memory.h>
39#include <osl/interlck.h>
40#include <rtl/alloc.h>
41#include <osl/diagnose.h>
42#include <rtl/tencinfo.h>
43
44#include "strimp.hxx"
45#include "surrogates.hxx"
46#include <rtl/string.h>
47
48#include "rtl/math.h"
49#include "rtl/tencinfo.h"
50
51/* ======================================================================= */
52
53/* static data to be referenced by all empty strings
54 * the refCount is predefined to 1 and must never become 0 !
55 */
56static rtl_String const aImplEmpty_rtl_String =
57{
58 SAL_STRING_STATIC_FLAG0x40000000|1,
59 /* sal_Int32 refCount; */
60 0, /* sal_Int32 length; */
61 { 0 } /* sal_Char buffer[1]; */
62};
63
64/* ======================================================================= */
65
66#define IMPL_RTL_STRCODEsal_Char sal_Char
67#define IMPL_RTL_USTRCODE( c )((unsigned char)c) ((unsigned char)c)
68#define IMPL_RTL_STRNAME( n )rtl_str_n rtl_str_ ## n
69
70#define IMPL_RTL_STRINGNAME( n )rtl_string_n rtl_string_ ## n
71#define IMPL_RTL_STRINGDATArtl_String rtl_String
72#define IMPL_RTL_EMPTYSTRINGaImplEmpty_rtl_String aImplEmpty_rtl_String
73
74#undef RTL_LOG_STRING_NEW
75#define RTL_LOG_STRING_NEW(s)
76#undef RTL_LOG_STRING_DELETE
77#define RTL_LOG_STRING_DELETE(s)
78
79/* ======================================================================= */
80
81/* Include String/UString template code */
82
83#include "strtmpl.cxx"
84
85sal_Int32 SAL_CALL rtl_str_valueOfFloat(sal_Char * pStr, float f)
86 SAL_THROW_EXTERN_C()throw ()
87{
88 rtl_String * pResult = NULL__null;
89 sal_Int32 nLen;
90 rtl_math_doubleToString(
91 &pResult, 0, 0, f, rtl_math_StringFormat_G,
92 RTL_STR_MAX_VALUEOFFLOAT15 - RTL_CONSTASCII_LENGTH("-x.E-xxx")((sal_Int32)((sizeof ("-x.E-xxx") / sizeof (("-x.E-xxx")[0]))
-1))
, '.', 0, 0,
93 sal_True((sal_Bool)1));
94 nLen = pResult->length;
95 OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFFLOAT)do { if (true && (!(nLen < 15))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "95" ": "), "OSL_ASSERT: %s", "nLen < RTL_STR_MAX_VALUEOFFLOAT"
); } } while (false)
;
96 memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char));
97 rtl_string_release(pResult);
98 return nLen;
99}
100
101sal_Int32 SAL_CALL rtl_str_valueOfDouble(sal_Char * pStr, double d)
102 SAL_THROW_EXTERN_C()throw ()
103{
104 rtl_String * pResult = NULL__null;
105 sal_Int32 nLen;
106 rtl_math_doubleToString(
107 &pResult, 0, 0, d, rtl_math_StringFormat_G,
108 RTL_STR_MAX_VALUEOFDOUBLE25 - RTL_CONSTASCII_LENGTH("-x.E-xxx")((sal_Int32)((sizeof ("-x.E-xxx") / sizeof (("-x.E-xxx")[0]))
-1))
, '.', 0,
109 0, sal_True((sal_Bool)1));
110 nLen = pResult->length;
111 OSL_ASSERT(nLen < RTL_STR_MAX_VALUEOFDOUBLE)do { if (true && (!(nLen < 25))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "111" ": "), "OSL_ASSERT: %s", "nLen < RTL_STR_MAX_VALUEOFDOUBLE"
); } } while (false)
;
112 memcpy(pStr, pResult->buffer, (nLen + 1) * sizeof(sal_Char));
113 rtl_string_release(pResult);
114 return nLen;
115}
116
117float SAL_CALL rtl_str_toFloat(sal_Char const * pStr) SAL_THROW_EXTERN_C()throw ()
118{
119 return (float) rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr),
120 '.', 0, 0, 0);
121}
122
123double SAL_CALL rtl_str_toDouble(sal_Char const * pStr) SAL_THROW_EXTERN_C()throw ()
124{
125 return rtl_math_stringToDouble(pStr, pStr + rtl_str_getLength(pStr), '.', 0,
126 0, 0);
127}
128
129/* ======================================================================= */
130
131static int rtl_ImplGetFastUTF8ByteLen( const sal_Unicode* pStr, sal_Int32 nLen )
132{
133 int n;
134 sal_Unicode c;
135 sal_uInt32 nUCS4Char;
136 const sal_Unicode* pEndStr;
137
138 n = 0;
139 pEndStr = pStr+nLen;
140 while ( pStr < pEndStr )
141 {
142 c = *pStr;
143
144 if ( c < 0x80 )
145 n++;
146 else if ( c < 0x800 )
147 n += 2;
148 else
149 {
150 if ( !SAL_RTL_IS_HIGH_SURROGATE(c)((c) >= 0xD800 && (c) <= 0xDBFF) )
151 n += 3;
152 else
153 {
154 nUCS4Char = c;
155
156 if ( pStr+1 < pEndStr )
157 {
158 c = *(pStr+1);
159 if ( SAL_RTL_IS_LOW_SURROGATE(c)((c) >= 0xDC00 && (c) <= 0xDFFF) )
160 {
161 nUCS4Char = SAL_RTL_COMBINE_SURROGATES(nUCS4Char, c)((((nUCS4Char) - 0xD800) << 10) + ((c) - 0xDC00) + 0x10000
)
;
162 pStr++;
163 }
164 }
165
166 if ( nUCS4Char < 0x10000 )
167 n += 3;
168 else if ( nUCS4Char < 0x200000 )
169 n += 4;
170 else if ( nUCS4Char < 0x4000000 )
171 n += 5;
172 else
173 n += 6;
174 }
175 }
176
177 pStr++;
178 }
179
180 return n;
181}
182
183/* ----------------------------------------------------------------------- */
184
185sal_Bool SAL_CALL rtl_impl_convertUStringToString(rtl_String ** pTarget,
186 sal_Unicode const * pSource,
187 sal_Int32 nLength,
188 rtl_TextEncoding nEncoding,
189 sal_uInt32 nFlags,
190 sal_Bool bCheckErrors)
191{
192 OSL_ASSERT(pTarget != NULLdo { if (true && (!(pTarget != __null && (pSource
!= __null || nLength == 0) && nLength >= 0 &&
(nLength == 0 || rtl_isOctetTextEncoding(nEncoding))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "195" ": "), "OSL_ASSERT: %s", "pTarget != NULL && (pSource != NULL || nLength == 0) && nLength >= 0 && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))"
); } } while (false)
193 && (pSource != NULL || nLength == 0)do { if (true && (!(pTarget != __null && (pSource
!= __null || nLength == 0) && nLength >= 0 &&
(nLength == 0 || rtl_isOctetTextEncoding(nEncoding))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "195" ": "), "OSL_ASSERT: %s", "pTarget != NULL && (pSource != NULL || nLength == 0) && nLength >= 0 && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))"
); } } while (false)
194 && nLength >= 0do { if (true && (!(pTarget != __null && (pSource
!= __null || nLength == 0) && nLength >= 0 &&
(nLength == 0 || rtl_isOctetTextEncoding(nEncoding))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "195" ": "), "OSL_ASSERT: %s", "pTarget != NULL && (pSource != NULL || nLength == 0) && nLength >= 0 && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))"
); } } while (false)
195 && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding)))do { if (true && (!(pTarget != __null && (pSource
!= __null || nLength == 0) && nLength >= 0 &&
(nLength == 0 || rtl_isOctetTextEncoding(nEncoding))))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "195" ": "), "OSL_ASSERT: %s", "pTarget != NULL && (pSource != NULL || nLength == 0) && nLength >= 0 && (nLength == 0 || rtl_isOctetTextEncoding(nEncoding))"
); } } while (false)
;
196
197 if ( !nLength )
2
Taking false branch
198 rtl_string_new( pTarget );
199 else
200 {
201 rtl_String* pTemp;
202 rtl_UnicodeToTextConverter hConverter;
203 sal_uInt32 nInfo;
204 sal_Size nSrcChars;
205 sal_Size nDestBytes;
206 sal_Size nNewLen;
207 sal_Size nNotConvertedChars;
208 sal_Size nMaxCharLen;
209
210 /* Optimization for UTF-8 - we try to calculate the exact length */
211 /* For all other encoding we try an good estimation */
212 if ( nEncoding == RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)) )
3
Taking true branch
213 {
214 nNewLen = rtl_ImplGetFastUTF8ByteLen( pSource, nLength );
215 /* Includes the string only ASCII, then we could copy
216 the buffer faster */
217 if ( nNewLen == (sal_Size)nLength )
4
Taking true branch
218 {
219 IMPL_RTL_STRCODEsal_Char* pBuffer;
220 if ( *pTarget )
5
Dereference of null pointer (loaded from variable 'pTarget')
221 IMPL_RTL_STRINGNAME( release )rtl_string_release( *pTarget );
222 *pTarget = IMPL_RTL_STRINGNAME( ImplAlloc )rtl_string_ImplAlloc( nLength );
223 OSL_ASSERT(*pTarget != NULL)do { if (true && (!(*pTarget != __null))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "223" ": "), "OSL_ASSERT: %s", "*pTarget != NULL"); } } while
(false)
;
224 pBuffer = (*pTarget)->buffer;
225 do
226 {
227 /* Check ASCII range */
228 OSL_ENSURE( *pSource <= 127,do { if (true && (!(*pSource <= 127))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "229" ": "), "%s", "rtl_uString2String() - UTF8 test is encoding is wrong"
); } } while (false)
229 "rtl_uString2String() - UTF8 test is encoding is wrong" )do { if (true && (!(*pSource <= 127))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "229" ": "), "%s", "rtl_uString2String() - UTF8 test is encoding is wrong"
); } } while (false)
;
230
231 *pBuffer = (IMPL_RTL_STRCODEsal_Char)(unsigned char)*pSource;
232 pBuffer++;
233 pSource++;
234 nLength--;
235 }
236 while ( nLength );
237 return sal_True((sal_Bool)1);
238 }
239
240 nMaxCharLen = 4;
241 }
242 else
243 {
244 rtl_TextEncodingInfo aTextEncInfo;
245 aTextEncInfo.StructSize = sizeof( aTextEncInfo );
246 if ( !rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo ) )
247 {
248 aTextEncInfo.AverageCharSize = 1;
249 aTextEncInfo.MaximumCharSize = 8;
250 }
251
252 nNewLen = nLength*aTextEncInfo.AverageCharSize;
253 nMaxCharLen = aTextEncInfo.MaximumCharSize;
254 }
255
256 nFlags |= RTL_UNICODETOTEXT_FLAGS_FLUSH((sal_uInt32)0x8000);
257 hConverter = rtl_createUnicodeToTextConverter( nEncoding );
258
259 for (;;)
260 {
261 pTemp = IMPL_RTL_STRINGNAME( ImplAlloc )rtl_string_ImplAlloc( nNewLen );
262 OSL_ASSERT(pTemp != NULL)do { if (true && (!(pTemp != __null))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "262" ": "), "OSL_ASSERT: %s", "pTemp != NULL"); } } while
(false)
;
263 nDestBytes = rtl_convertUnicodeToText( hConverter, 0,
264 pSource, nLength,
265 pTemp->buffer, nNewLen,
266 nFlags,
267 &nInfo, &nSrcChars );
268 if (bCheckErrors && (nInfo & RTL_UNICODETOTEXT_INFO_ERROR((sal_uInt32)0x0001)) != 0)
269 {
270 rtl_freeMemory(pTemp);
271 rtl_destroyUnicodeToTextConverter(hConverter);
272 return sal_False((sal_Bool)0);
273 }
274
275 if ((nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL((sal_uInt32)0x0004)) == 0)
276 break;
277
278 /* Buffer not big enough, try again with enough space */
279 rtl_freeMemory( pTemp );
280
281 /* Try with the max. count of characters with
282 additional overhead for replacing functionality */
283 nNotConvertedChars = nLength-nSrcChars;
284 nNewLen = nDestBytes+(nNotConvertedChars*nMaxCharLen)+nNotConvertedChars+4;
285 }
286
287 /* Set the buffer to the correct size or is there to
288 much overhead, reallocate to the correct size */
289 if ( nNewLen > nDestBytes+8 )
290 {
291 rtl_String* pTemp2 = IMPL_RTL_STRINGNAME( ImplAlloc )rtl_string_ImplAlloc( nDestBytes );
292 OSL_ASSERT(pTemp2 != NULL)do { if (true && (!(pTemp2 != __null))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
":" "292" ": "), "OSL_ASSERT: %s", "pTemp2 != NULL"); } } while
(false)
;
293 rtl_str_ImplCopy( pTemp2->buffer, pTemp->buffer, nDestBytes ){ sal_Char* __mm_pDest = pTemp2->buffer; const sal_Char* __mm_pSrc
= pTemp->buffer; sal_Int32 __mm_nCount = nDestBytes; while
( __mm_nCount > 0 ) { *__mm_pDest = *__mm_pSrc; __mm_pDest
++; __mm_pSrc++; __mm_nCount--; } }
;
294 rtl_freeMemory( pTemp );
295 pTemp = pTemp2;
296 }
297 else
298 {
299 pTemp->length = nDestBytes;
300 pTemp->buffer[nDestBytes] = 0;
301 }
302
303 rtl_destroyUnicodeToTextConverter( hConverter );
304 if ( *pTarget )
305 IMPL_RTL_STRINGNAME( release )rtl_string_release( *pTarget );
306 *pTarget = pTemp;
307
308 /* Results the conversion in an empty buffer -
309 create an empty string */
310 if ( pTemp && !nDestBytes )
311 rtl_string_new( pTarget );
312 }
313 return sal_True((sal_Bool)1);
314}
315
316void SAL_CALL rtl_uString2String( rtl_String** ppThis,
317 const sal_Unicode* pUStr,
318 sal_Int32 nULen,
319 rtl_TextEncoding eTextEncoding,
320 sal_uInt32 nCvtFlags )
321 SAL_THROW_EXTERN_C()throw ()
322{
323 rtl_impl_convertUStringToString(ppThis, pUStr, nULen, eTextEncoding,
324 nCvtFlags, sal_False((sal_Bool)0));
325}
326
327sal_Bool SAL_CALL rtl_convertUStringToString(rtl_String ** pTarget,
328 sal_Unicode const * pSource,
329 sal_Int32 nLength,
330 rtl_TextEncoding nEncoding,
331 sal_uInt32 nFlags)
332 SAL_THROW_EXTERN_C()throw ()
333{
334 return rtl_impl_convertUStringToString(pTarget, pSource, nLength, nEncoding,
1
Calling 'rtl_impl_convertUStringToString'
335 nFlags, sal_True((sal_Bool)1));
336}
337
338void rtl_string_newReplaceFirst(
339 rtl_String ** newStr, rtl_String * str, char const * from,
340 sal_Int32 fromLength, char const * to, sal_Int32 toLength,
341 sal_Int32 * index) SAL_THROW_EXTERN_C()throw ()
342{
343 assert(str != 0)((str != 0) ? static_cast<void> (0) : __assert_fail ("str != 0"
, "/usr/local/src/libreoffice/sal/rtl/source/string.cxx", 343
, __PRETTY_FUNCTION__))
;
344 assert(index != 0)((index != 0) ? static_cast<void> (0) : __assert_fail (
"index != 0", "/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
, 344, __PRETTY_FUNCTION__))
;
345 assert(*index >= 0 && *index <= str->length)((*index >= 0 && *index <= str->length) ? static_cast
<void> (0) : __assert_fail ("*index >= 0 && *index <= str->length"
, "/usr/local/src/libreoffice/sal/rtl/source/string.cxx", 345
, __PRETTY_FUNCTION__))
;
346 assert(fromLength >= 0)((fromLength >= 0) ? static_cast<void> (0) : __assert_fail
("fromLength >= 0", "/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
, 346, __PRETTY_FUNCTION__))
;
347 assert(toLength >= 0)((toLength >= 0) ? static_cast<void> (0) : __assert_fail
("toLength >= 0", "/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
, 347, __PRETTY_FUNCTION__))
;
348 sal_Int32 i = rtl_str_indexOfStr_WithLength(
349 str->buffer + *index, str->length - *index, from, fromLength);
350 if (i == -1) {
351 rtl_string_assign(newStr, str);
352 } else {
353 assert(i <= str->length - *index)((i <= str->length - *index) ? static_cast<void> (
0) : __assert_fail ("i <= str->length - *index", "/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
, 353, __PRETTY_FUNCTION__))
;
354 i += *index;
355 assert(fromLength <= str->length)((fromLength <= str->length) ? static_cast<void> (
0) : __assert_fail ("fromLength <= str->length", "/usr/local/src/libreoffice/sal/rtl/source/string.cxx"
, 355, __PRETTY_FUNCTION__))
;
356 if (str->length - fromLength > SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF) - toLength) {
357 std::abort();
358 }
359 sal_Int32 n = str->length - fromLength + toLength;
360 rtl_string_acquire(str); // in case *newStr == str
361 rtl_string_new_WithLength(newStr, n);
362 if (n != 0) {
363 (*newStr)->length = n;
364 assert(i >= 0 && i < str->length)((i >= 0 && i < str->length) ? static_cast<
void> (0) : __assert_fail ("i >= 0 && i < str->length"
, "/usr/local/src/libreoffice/sal/rtl/source/string.cxx", 364
, __PRETTY_FUNCTION__))
;
365 memcpy((*newStr)->buffer, str->buffer, i);
366 memcpy((*newStr)->buffer + i, to, toLength);
367 memcpy(
368 (*newStr)->buffer + i + toLength, str->buffer + i + fromLength,
369 str->length - i - fromLength);
370 }
371 rtl_string_release(str);
372 }
373 *index = i;
374}
375
376void rtl_string_newReplaceAll(
377 rtl_String ** newStr, rtl_String * str, char const * from,
378 sal_Int32 fromLength, char const * to, sal_Int32 toLength)
379 SAL_THROW_EXTERN_C()throw ()
380{
381 rtl_string_assign(newStr, str);
382 for (sal_Int32 i = 0;; i += toLength) {
383 rtl_string_newReplaceFirst(
384 newStr, *newStr, from, fromLength, to, toLength, &i);
385 if (i == -1) {
386 break;
387 }
388 }
389}
390
391/* vim:set shiftwidth=4 softtabstop=4 expandtab: */