File: | comphelper/source/misc/anytostring.cxx |
Location: | line 207, column 9 |
Description: | Dereference of null pointer |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | ||||
21 | #include "comphelper/anytostring.hxx" | |||
22 | #include "osl/diagnose.h" | |||
23 | #include "rtl/ustrbuf.hxx" | |||
24 | #include "typelib/typedescription.h" | |||
25 | #include "com/sun/star/lang/XServiceInfo.hpp" | |||
26 | ||||
27 | using namespace ::com::sun::star; | |||
28 | ||||
29 | namespace comphelper { | |||
30 | namespace { | |||
31 | ||||
32 | void appendTypeError( | |||
33 | rtl::OUStringBuffer & buf, typelib_TypeDescriptionReference * typeRef ) | |||
34 | { | |||
35 | buf.appendAscii( | |||
36 | RTL_CONSTASCII_STRINGPARAM("<cannot get type description of type ")(&("<cannot get type description of type ")[0]), ((sal_Int32 )(sizeof ("<cannot get type description of type ") / sizeof (("<cannot get type description of type ")[0]))-1) ); | |||
37 | buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); | |||
38 | buf.append( static_cast< sal_Unicode >('>') ); | |||
39 | } | |||
40 | ||||
41 | inline void appendChar( rtl::OUStringBuffer & buf, sal_Unicode c ) | |||
42 | { | |||
43 | if (c < ' ' || c > '~') { | |||
44 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\X")(&("\\X")[0]), ((sal_Int32)(sizeof ("\\X") / sizeof (("\\X" )[0]))-1) ); | |||
45 | rtl::OUString const s( | |||
46 | rtl::OUString::valueOf( static_cast< sal_Int32 >(c), 16 ) ); | |||
47 | for ( sal_Int32 f = 4 - s.getLength(); f > 0; --f ) | |||
48 | buf.append( static_cast< sal_Unicode >('0') ); | |||
49 | buf.append( s ); | |||
50 | } | |||
51 | else { | |||
52 | buf.append( c ); | |||
53 | } | |||
54 | } | |||
55 | ||||
56 | //------------------------------------------------------------------------------ | |||
57 | void appendValue( rtl::OUStringBuffer & buf, | |||
58 | void const * val, typelib_TypeDescriptionReference * typeRef, | |||
59 | bool prependType ) | |||
60 | { | |||
61 | if (typeRef->eTypeClass == typelib_TypeClass_VOID) { | |||
62 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("void")(&("void")[0]), ((sal_Int32)(sizeof ("void") / sizeof (("void" )[0]))-1) ); | |||
63 | return; | |||
64 | } | |||
65 | OSL_ASSERT( val != 0 )do { if (true && (!(val != 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/usr/local/src/libreoffice/comphelper/source/misc/anytostring.cxx" ":" "65" ": "), "OSL_ASSERT: %s", "val != 0"); } } while (false ); | |||
66 | ||||
67 | if (prependType && | |||
68 | typeRef->eTypeClass != typelib_TypeClass_STRING && | |||
69 | typeRef->eTypeClass != typelib_TypeClass_CHAR && | |||
70 | typeRef->eTypeClass != typelib_TypeClass_BOOLEAN) | |||
71 | { | |||
72 | buf.append( static_cast< sal_Unicode >('(') ); | |||
73 | buf.append( rtl::OUString::unacquired( &typeRef->pTypeName ) ); | |||
74 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(") ")(&(") ")[0]), ((sal_Int32)(sizeof (") ") / sizeof ((") ") [0]))-1) ); | |||
75 | } | |||
76 | ||||
77 | switch (typeRef->eTypeClass) { | |||
78 | case typelib_TypeClass_INTERFACE: { | |||
79 | buf.append( static_cast<sal_Unicode>('@') ); | |||
80 | buf.append( reinterpret_cast< sal_Int64 >( | |||
81 | *static_cast< void * const * >(val) ), 16 ); | |||
82 | uno::Reference< lang::XServiceInfo > xServiceInfo( | |||
83 | *static_cast< uno::XInterface * const * >(val), | |||
84 | uno::UNO_QUERY ); | |||
85 | if (xServiceInfo.is()) { | |||
86 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM((&(" (ImplementationName = \"")[0]), ((sal_Int32)(sizeof ( " (ImplementationName = \"") / sizeof ((" (ImplementationName = \"" )[0]))-1) | |||
87 | " (ImplementationName = \"")(&(" (ImplementationName = \"")[0]), ((sal_Int32)(sizeof ( " (ImplementationName = \"") / sizeof ((" (ImplementationName = \"" )[0]))-1) ); | |||
88 | buf.append( xServiceInfo->getImplementationName() ); | |||
89 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")")(&("\")")[0]), ((sal_Int32)(sizeof ("\")") / sizeof (("\")" )[0]))-1) ); | |||
90 | } | |||
91 | break; | |||
92 | } | |||
93 | case typelib_TypeClass_STRUCT: | |||
94 | case typelib_TypeClass_EXCEPTION: { | |||
95 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ")(&("{ ")[0]), ((sal_Int32)(sizeof ("{ ") / sizeof (("{ ") [0]))-1) ); | |||
96 | typelib_TypeDescription * typeDescr = 0; | |||
97 | typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); | |||
98 | if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { | |||
99 | appendTypeError( buf, typeRef ); | |||
100 | } | |||
101 | else { | |||
102 | typelib_CompoundTypeDescription * compType = | |||
103 | reinterpret_cast< typelib_CompoundTypeDescription * >( | |||
104 | typeDescr ); | |||
105 | sal_Int32 nDescr = compType->nMembers; | |||
106 | ||||
107 | if (compType->pBaseTypeDescription) { | |||
108 | appendValue( | |||
109 | buf, val, reinterpret_cast< | |||
110 | typelib_TypeDescription * >( | |||
111 | compType->pBaseTypeDescription)->pWeakRef, false ); | |||
112 | if (nDescr > 0) | |||
113 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ")(&(", ")[0]), ((sal_Int32)(sizeof (", ") / sizeof ((", ") [0]))-1) ); | |||
114 | } | |||
115 | ||||
116 | typelib_TypeDescriptionReference ** ppTypeRefs = | |||
117 | compType->ppTypeRefs; | |||
118 | sal_Int32 * memberOffsets = compType->pMemberOffsets; | |||
119 | rtl_uString ** ppMemberNames = compType->ppMemberNames; | |||
120 | ||||
121 | for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) | |||
122 | { | |||
123 | buf.append( ppMemberNames[ nPos ] ); | |||
124 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ")(&(" = ")[0]), ((sal_Int32)(sizeof (" = ") / sizeof ((" = " )[0]))-1) ); | |||
125 | typelib_TypeDescription * memberType = 0; | |||
126 | TYPELIB_DANGER_GET( &memberType, ppTypeRefs[ nPos ] ){ typelib_TypeDescriptionReference * pMacroTypeRef = (ppTypeRefs [ nPos ]); typelib_TypeDescription ** ppMacroTypeDescr = (& memberType); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
127 | if (memberType == 0) { | |||
128 | appendTypeError( buf, ppTypeRefs[ nPos ] ); | |||
129 | } | |||
130 | else { | |||
131 | appendValue( buf, | |||
132 | static_cast< char const * >( | |||
133 | val ) + memberOffsets[ nPos ], | |||
134 | memberType->pWeakRef, true ); | |||
135 | TYPELIB_DANGER_RELEASE( memberType ){ if ((((memberType)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((memberType)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( memberType ); }; | |||
136 | } | |||
137 | if (nPos < (nDescr - 1)) | |||
138 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ")(&(", ")[0]), ((sal_Int32)(sizeof (", ") / sizeof ((", ") [0]))-1) ); | |||
139 | } | |||
140 | } | |||
141 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }")(&(" }")[0]), ((sal_Int32)(sizeof (" }") / sizeof ((" }") [0]))-1) ); | |||
142 | if (typeDescr != 0) | |||
143 | typelib_typedescription_release( typeDescr ); | |||
144 | break; | |||
145 | } | |||
146 | case typelib_TypeClass_SEQUENCE: { | |||
147 | typelib_TypeDescription * typeDescr = 0; | |||
148 | TYPELIB_DANGER_GET( &typeDescr, typeRef ){ typelib_TypeDescriptionReference * pMacroTypeRef = (typeRef ); typelib_TypeDescription ** ppMacroTypeDescr = (&typeDescr ); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
149 | if (typeDescr == 0) { | |||
150 | appendTypeError( buf,typeRef ); | |||
151 | } | |||
152 | else { | |||
153 | typelib_TypeDescriptionReference * elementTypeRef = | |||
154 | reinterpret_cast< | |||
155 | typelib_IndirectTypeDescription * >(typeDescr)->pType; | |||
156 | typelib_TypeDescription * elementTypeDescr = 0; | |||
157 | TYPELIB_DANGER_GET( &elementTypeDescr, elementTypeRef ){ typelib_TypeDescriptionReference * pMacroTypeRef = (elementTypeRef ); typelib_TypeDescription ** ppMacroTypeDescr = (&elementTypeDescr ); if (((pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || (pMacroTypeRef->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) { typelib_typedescriptionreference_getDescription( ppMacroTypeDescr , pMacroTypeRef ); } else if (!pMacroTypeRef->pType || !pMacroTypeRef ->pType->pWeakRef) { typelib_typedescriptionreference_getDescription ( ppMacroTypeDescr, pMacroTypeRef ); if (*ppMacroTypeDescr) typelib_typedescription_release ( *ppMacroTypeDescr ); } else { *ppMacroTypeDescr = pMacroTypeRef ->pType; } }; | |||
158 | if (elementTypeDescr == 0) | |||
159 | { | |||
160 | appendTypeError( buf, elementTypeRef ); | |||
161 | } | |||
162 | else | |||
163 | { | |||
164 | sal_Int32 nElementSize = elementTypeDescr->nSize; | |||
165 | uno_Sequence * seq = | |||
166 | *static_cast< uno_Sequence * const * >(val); | |||
167 | sal_Int32 nElements = seq->nElements; | |||
168 | ||||
169 | if (nElements > 0) | |||
170 | { | |||
171 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ")(&("{ ")[0]), ((sal_Int32)(sizeof ("{ ") / sizeof (("{ ") [0]))-1) ); | |||
172 | char const * pElements = seq->elements; | |||
173 | for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) | |||
174 | { | |||
175 | appendValue( | |||
176 | buf, pElements + (nElementSize * nPos), | |||
177 | elementTypeDescr->pWeakRef, false ); | |||
178 | if (nPos < (nElements - 1)) | |||
179 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ")(&(", ")[0]), ((sal_Int32)(sizeof (", ") / sizeof ((", ") [0]))-1) ); | |||
180 | } | |||
181 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }")(&(" }")[0]), ((sal_Int32)(sizeof (" }") / sizeof ((" }") [0]))-1) ); | |||
182 | } | |||
183 | else | |||
184 | { | |||
185 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}")(&("{}")[0]), ((sal_Int32)(sizeof ("{}") / sizeof (("{}") [0]))-1) ); | |||
186 | } | |||
187 | TYPELIB_DANGER_RELEASE( elementTypeDescr ){ if ((((elementTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((elementTypeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( elementTypeDescr ); }; | |||
188 | } | |||
189 | TYPELIB_DANGER_RELEASE( typeDescr ){ if ((((typeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_METHOD || ((typeDescr)->eTypeClass) == typelib_TypeClass_INTERFACE_ATTRIBUTE )) typelib_typedescription_release( typeDescr ); }; | |||
190 | } | |||
191 | break; | |||
192 | } | |||
193 | case typelib_TypeClass_ANY: { | |||
194 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ")(&("{ ")[0]), ((sal_Int32)(sizeof ("{ ") / sizeof (("{ ") [0]))-1) ); | |||
195 | uno_Any const * pAny = static_cast< uno_Any const * >(val); | |||
196 | appendValue( buf, pAny->pData, pAny->pType, true ); | |||
197 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }")(&(" }")[0]), ((sal_Int32)(sizeof (" }") / sizeof ((" }") [0]))-1) ); | |||
198 | break; | |||
199 | } | |||
200 | case typelib_TypeClass_TYPE: | |||
201 | buf.append( (*reinterpret_cast< | |||
202 | typelib_TypeDescriptionReference * const * >(val) | |||
203 | )->pTypeName ); | |||
204 | break; | |||
205 | case typelib_TypeClass_STRING: { | |||
206 | buf.append( static_cast< sal_Unicode >('\"') ); | |||
207 | rtl::OUString const & str = rtl::OUString::unacquired( | |||
| ||||
208 | static_cast< rtl_uString * const * >(val) ); | |||
209 | sal_Int32 len = str.getLength(); | |||
210 | for ( sal_Int32 pos = 0; pos < len; ++pos ) | |||
211 | { | |||
212 | sal_Unicode c = str[ pos ]; | |||
213 | if (c == '\"') | |||
214 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\"")(&("\\\"")[0]), ((sal_Int32)(sizeof ("\\\"") / sizeof (("\\\"" )[0]))-1) ); | |||
215 | else if (c == '\\') | |||
216 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\")(&("\\\\")[0]), ((sal_Int32)(sizeof ("\\\\") / sizeof (("\\\\" )[0]))-1) ); | |||
217 | else | |||
218 | appendChar( buf, c ); | |||
219 | } | |||
220 | buf.append( static_cast< sal_Unicode >('\"') ); | |||
221 | break; | |||
222 | } | |||
223 | case typelib_TypeClass_ENUM: { | |||
224 | typelib_TypeDescription * typeDescr = 0; | |||
225 | typelib_typedescriptionreference_getDescription( &typeDescr, typeRef ); | |||
226 | if (typeDescr == 0 || !typelib_typedescription_complete( &typeDescr )) { | |||
227 | appendTypeError( buf, typeRef ); | |||
228 | } | |||
229 | else | |||
230 | { | |||
231 | sal_Int32 * pValues = | |||
232 | reinterpret_cast< typelib_EnumTypeDescription * >( | |||
233 | typeDescr )->pEnumValues; | |||
234 | sal_Int32 nPos = reinterpret_cast< typelib_EnumTypeDescription * >( | |||
235 | typeDescr )->nEnumValues; | |||
236 | while (nPos--) | |||
237 | { | |||
238 | if (pValues[ nPos ] == *static_cast< int const * >(val)) | |||
239 | break; | |||
240 | } | |||
241 | if (nPos >= 0) | |||
242 | { | |||
243 | buf.append( reinterpret_cast< typelib_EnumTypeDescription * >( | |||
244 | typeDescr )->ppEnumNames[ nPos ] ); | |||
245 | } | |||
246 | else | |||
247 | { | |||
248 | buf.appendAscii( | |||
249 | RTL_CONSTASCII_STRINGPARAM("?unknown enum value?")(&("?unknown enum value?")[0]), ((sal_Int32)(sizeof ("?unknown enum value?" ) / sizeof (("?unknown enum value?")[0]))-1) ); | |||
250 | } | |||
251 | } | |||
252 | if (typeDescr != 0) | |||
253 | typelib_typedescription_release( typeDescr ); | |||
254 | break; | |||
255 | } | |||
256 | case typelib_TypeClass_BOOLEAN: | |||
257 | if (*static_cast< sal_Bool const * >(val) != sal_False((sal_Bool)0)) | |||
258 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true")(&("true")[0]), ((sal_Int32)(sizeof ("true") / sizeof (("true" )[0]))-1) ); | |||
259 | else | |||
260 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false")(&("false")[0]), ((sal_Int32)(sizeof ("false") / sizeof ( ("false")[0]))-1) ); | |||
261 | break; | |||
262 | case typelib_TypeClass_CHAR: { | |||
263 | buf.append( static_cast< sal_Unicode >('\'') ); | |||
264 | sal_Unicode c = *static_cast< sal_Unicode const * >(val); | |||
265 | if (c == '\'') | |||
266 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\'")(&("\\\'")[0]), ((sal_Int32)(sizeof ("\\\'") / sizeof (("\\\'" )[0]))-1) ); | |||
267 | else if (c == '\\') | |||
268 | buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\\\\")(&("\\\\")[0]), ((sal_Int32)(sizeof ("\\\\") / sizeof (("\\\\" )[0]))-1) ); | |||
269 | else | |||
270 | appendChar( buf, c ); | |||
271 | buf.append( static_cast< sal_Unicode >('\'') ); | |||
272 | break; | |||
273 | } | |||
274 | case typelib_TypeClass_FLOAT: | |||
275 | buf.append( *static_cast< float const * >(val) ); | |||
276 | break; | |||
277 | case typelib_TypeClass_DOUBLE: | |||
278 | buf.append( *static_cast< double const * >(val) ); | |||
279 | break; | |||
280 | case typelib_TypeClass_BYTE: | |||
281 | buf.append( static_cast< sal_Int32 >( | |||
282 | *static_cast< sal_Int8 const * >(val) ) ); | |||
283 | break; | |||
284 | case typelib_TypeClass_SHORT: | |||
285 | buf.append( static_cast< sal_Int32 >( | |||
286 | *static_cast< sal_Int16 const * >(val) ) ); | |||
287 | break; | |||
288 | case typelib_TypeClass_UNSIGNED_SHORT: | |||
289 | buf.append( static_cast< sal_Int32 >( | |||
290 | *static_cast< sal_uInt16 const * >(val) ) ); | |||
291 | break; | |||
292 | case typelib_TypeClass_LONG: | |||
293 | buf.append( *static_cast< sal_Int32 const * >(val) ); | |||
294 | break; | |||
295 | case typelib_TypeClass_UNSIGNED_LONG: | |||
296 | buf.append( static_cast< sal_Int64 >( | |||
297 | *static_cast< sal_uInt32 const * >(val) ) ); | |||
298 | break; | |||
299 | case typelib_TypeClass_HYPER: | |||
300 | case typelib_TypeClass_UNSIGNED_HYPER: | |||
301 | buf.append( *static_cast< sal_Int64 const * >(val) ); | |||
302 | break; | |||
303 | // case typelib_TypeClass_UNION: | |||
304 | // case typelib_TypeClass_ARRAY: | |||
305 | // case typelib_TypeClass_UNKNOWN: | |||
306 | // case typelib_TypeClass_SERVICE: | |||
307 | // case typelib_TypeClass_MODULE: | |||
308 | default: | |||
309 | buf.append( static_cast< sal_Unicode >('?') ); | |||
310 | break; | |||
311 | } | |||
312 | } | |||
313 | ||||
314 | } // anon namespace | |||
315 | ||||
316 | //============================================================================== | |||
317 | rtl::OUString anyToString( uno::Any const & value ) | |||
318 | { | |||
319 | rtl::OUStringBuffer buf; | |||
320 | appendValue( buf, value.getValue(), value.getValueTypeRef(), true ); | |||
| ||||
321 | return buf.makeStringAndClear(); | |||
322 | } | |||
323 | ||||
324 | } // namespace comphelper | |||
325 | ||||
326 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |