Bug Summary

File:src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_data.c
Location:line 111, column 5
Description:Access to field '_refcount' results in a dereference of a null pointer (loaded from variable 'valueP')

Annotated Source Code

1/* Copyright information is at end of file */
2
3#include "xmlrpc_config.h"
4
5#include <stddef.h>
6#include <stdlib.h>
7#include <stdarg.h>
8#include <string.h>
9
10#include "bool.h"
11#include "mallocvar.h"
12
13#include "xmlrpc-c/base.h"
14#include "xmlrpc-c/base_int.h"
15
16
17
18static void
19destroyCptr(xmlrpc_value * const valueP) {
20
21 if (valueP->_value.cptr.dtor)
22 valueP->_value.cptr.dtor(valueP->_value.cptr.dtorContext,
23 valueP->_value.cptr.objectP);
24}
25
26
27
28static void
29destroyValue(xmlrpc_value * const valueP) {
30
31 /* First, we need to destroy this value's contents, if any. */
32 switch (valueP->_type) {
33 case XMLRPC_TYPE_INT:
34 break;
35
36 case XMLRPC_TYPE_BOOL:
37 break;
38
39 case XMLRPC_TYPE_DOUBLE:
40 break;
41
42 case XMLRPC_TYPE_DATETIME:
43 xmlrpc_destroyDatetime(valueP);
44 break;
45
46 case XMLRPC_TYPE_STRING:
47 xmlrpc_destroyString(valueP);
48 break;
49
50 case XMLRPC_TYPE_BASE64:
51 xmlrpc_mem_block_clean(&valueP->_block);
52 break;
53
54 case XMLRPC_TYPE_ARRAY:
55 xmlrpc_destroyArrayContents(valueP);
56 break;
57
58 case XMLRPC_TYPE_STRUCT:
59 xmlrpc_destroyStruct(valueP);
60 break;
61
62 case XMLRPC_TYPE_C_PTR:
63 destroyCptr(valueP);
64 break;
65
66 case XMLRPC_TYPE_NIL:
67 break;
68
69 case XMLRPC_TYPE_I8:
70 break;
71
72 case XMLRPC_TYPE_DEAD:
73 XMLRPC_ASSERT(false)do if (!(false)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_data.c"
, 73); while (0)
; /* Can't happen, per entry conditions */
74
75 default:
76 XMLRPC_ASSERT(false)do if (!(false)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_data.c"
, 76); while (0)
; /* There are no other possible values */
77 }
78
79 /* Next, we mark this value as invalid, to help catch refcount
80 ** errors. */
81 valueP->_type = XMLRPC_TYPE_DEAD;
82
83 /* Finally, we destroy the value itself. */
84 free(valueP);
85}
86
87
88
89/*=========================================================================
90** Reference Counting
91**=========================================================================
92** Some simple reference-counting code. The xmlrpc_DECREF routine is in
93** charge of destroying values when their reference count equals zero.
94*/
95
96void
97xmlrpc_INCREF (xmlrpc_value * const valueP) {
98
99 XMLRPC_ASSERT_VALUE_OK(valueP)do if (!((valueP) != ((void*)0) && (valueP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_data.c"
, 99); while (0)
;
100 XMLRPC_ASSERT(valueP->_refcount > 0)do if (!(valueP->_refcount > 0)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_data.c", 100); while (
0)
;
101
102 ++valueP->_refcount;
103}
104
105
106
107void
108xmlrpc_DECREF (xmlrpc_value * const valueP) {
109
110 XMLRPC_ASSERT_VALUE_OK(valueP)do if (!((valueP) != ((void*)0) && (valueP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_data.c"
, 110); while (0)
;
1
Within the expansion of the macro 'XMLRPC_ASSERT_VALUE_OK':
a
Assuming 'valueP' is equal to null
111 XMLRPC_ASSERT(valueP->_refcount > 0)do if (!(valueP->_refcount > 0)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_data.c", 111); while (
0)
;
2
Within the expansion of the macro 'XMLRPC_ASSERT':
a
Access to field '_refcount' results in a dereference of a null pointer (loaded from variable 'valueP')
112 XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD)do if (!(valueP->_type != XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_data.c", 112); while (
0)
;
113
114 valueP->_refcount--;
115
116 /* If we have no more refs, we need to deallocate this value. */
117 if (valueP->_refcount == 0)
118 destroyValue(valueP);
119}
120
121
122
123/*=========================================================================
124 Utiltiies
125=========================================================================*/
126
127const char *
128xmlrpc_type_name(xmlrpc_type const type) {
129
130 switch (type) {
131
132 case XMLRPC_TYPE_INT: return "INT";
133 case XMLRPC_TYPE_BOOL: return "BOOL";
134 case XMLRPC_TYPE_DOUBLE: return "DOUBLE";
135 case XMLRPC_TYPE_DATETIME: return "DATETIME";
136 case XMLRPC_TYPE_STRING: return "STRING";
137 case XMLRPC_TYPE_BASE64: return "BASE64";
138 case XMLRPC_TYPE_ARRAY: return "ARRAY";
139 case XMLRPC_TYPE_STRUCT: return "STRUCT";
140 case XMLRPC_TYPE_C_PTR: return "C_PTR";
141 case XMLRPC_TYPE_NIL: return "NIL";
142 case XMLRPC_TYPE_I8: return "I8";
143 case XMLRPC_TYPE_DEAD: return "DEAD";
144 default: return "???";
145
146 }
147}
148
149
150
151static void
152validateType(xmlrpc_env * const envP,
153 const xmlrpc_value * const valueP,
154 xmlrpc_type const expectedType) {
155
156 if (valueP->_type != expectedType) {
157 xmlrpc_env_set_fault_formatted(
158 envP, XMLRPC_TYPE_ERROR(-501), "Value of type %s supplied where "
159 "type %s was expected.",
160 xmlrpc_type_name(valueP->_type), xmlrpc_type_name(expectedType));
161 }
162}
163
164
165
166/*=========================================================================
167 Extracting XML-RPC value
168===========================================================================
169 These routines extract XML-RPC values into ordinary C data types.
170
171 For array and struct values, see the separates files xmlrpc_array.c
172 and xmlrpc_struct.c.
173=========================================================================*/
174
175void
176xmlrpc_read_int(xmlrpc_env * const envP,
177 const xmlrpc_value * const valueP,
178 xmlrpc_int32 * const intValueP) {
179
180 validateType(envP, valueP, XMLRPC_TYPE_INT);
181 if (!envP->fault_occurred)
182 *intValueP = valueP->_value.i;
183}
184
185
186
187void
188xmlrpc_read_bool(xmlrpc_env * const envP,
189 const xmlrpc_value * const valueP,
190 xmlrpc_bool * const boolValueP) {
191
192 validateType(envP, valueP, XMLRPC_TYPE_BOOL);
193 if (!envP->fault_occurred)
194 *boolValueP = valueP->_value.b;
195}
196
197
198
199void
200xmlrpc_read_double(xmlrpc_env * const envP,
201 const xmlrpc_value * const valueP,
202 xmlrpc_double * const doubleValueP) {
203
204 validateType(envP, valueP, XMLRPC_TYPE_DOUBLE);
205 if (!envP->fault_occurred)
206 *doubleValueP = valueP->_value.d;
207
208}
209
210
211
212/* datetime stuff is in xmlrpc_datetime.c */
213
214/* string stuff is in xmlrpc_string.c */
215
216
217
218void
219xmlrpc_read_base64(xmlrpc_env * const envP,
220 const xmlrpc_value * const valueP,
221 size_t * const lengthP,
222 const unsigned char ** const byteStringValueP) {
223
224 validateType(envP, valueP, XMLRPC_TYPE_BASE64);
225 if (!envP->fault_occurred) {
226 size_t const size =
227 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
;
228 const char * const contents =
229 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
230
231 char * byteStringValue;
232
233 byteStringValue = malloc(size);
234 if (byteStringValue == NULL((void*)0))
235 xmlrpc_faultf(envP,
236 "Unable to allocate %u bytes for byte string.",
237 (unsigned)size);
238 else {
239 memcpy(byteStringValue, contents, size);
240 *byteStringValueP = (const unsigned char *)byteStringValue;
241 *lengthP = size;
242 }
243 }
244}
245
246
247
248void
249xmlrpc_read_base64_old(xmlrpc_env * const envP,
250 const xmlrpc_value * const valueP,
251 size_t * const lengthP,
252 const unsigned char ** const byteStringValueP) {
253
254 validateType(envP, valueP, XMLRPC_TYPE_BASE64);
255 if (!envP->fault_occurred) {
256 *lengthP =
257 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
;
258 *byteStringValueP = (const unsigned char *)
259 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
260 }
261}
262
263
264
265void
266xmlrpc_read_base64_size(xmlrpc_env * const envP,
267 const xmlrpc_value * const valueP,
268 size_t * const lengthP) {
269
270 validateType(envP, valueP, XMLRPC_TYPE_BASE64);
271 if (!envP->fault_occurred)
272 *lengthP = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
;
273}
274
275
276
277void
278xmlrpc_read_cptr(xmlrpc_env * const envP,
279 const xmlrpc_value * const valueP,
280 void ** const ptrValueP) {
281
282 validateType(envP, valueP, XMLRPC_TYPE_C_PTR);
283 if (!envP->fault_occurred)
284 *ptrValueP = valueP->_value.cptr.objectP;
285}
286
287
288
289void
290xmlrpc_read_nil(xmlrpc_env * const envP,
291 xmlrpc_value * const valueP) {
292/*----------------------------------------------------------------------------
293 Read out the value of a nil value. It doesn't have one, of course, so
294 this is essentially a no-op. But it does validate the type and is
295 necessary to match all the other types.
296-----------------------------------------------------------------------------*/
297 validateType(envP, valueP, XMLRPC_TYPE_NIL);
298}
299
300
301
302void
303xmlrpc_read_i8(xmlrpc_env * const envP,
304 const xmlrpc_value * const valueP,
305 xmlrpc_int64 * const intValueP) {
306
307 validateType(envP, valueP, XMLRPC_TYPE_I8);
308 if (!envP->fault_occurred)
309 *intValueP = valueP->_value.i8;
310}
311
312
313
314xmlrpc_type xmlrpc_value_type (xmlrpc_value* const value)
315{
316 XMLRPC_ASSERT_VALUE_OK(value)do if (!((value) != ((void*)0) && (value)->_type !=
XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_data.c"
, 316); while (0)
;
317 return value->_type;
318}
319
320
321
322void
323xmlrpc_createXmlrpcValue(xmlrpc_env * const envP,
324 xmlrpc_value ** const valPP) {
325/*----------------------------------------------------------------------------
326 Create a blank xmlrpc_value to be filled in.
327
328 Set the reference count to 1.
329-----------------------------------------------------------------------------*/
330 xmlrpc_value * valP;
331
332 MALLOCVAR(valP)valP = malloc(sizeof(*valP));
333 if (!valP)
334 xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR(-500),
335 "Could not allocate memory for xmlrpc_value");
336 else
337 valP->_refcount = 1;
338
339 *valPP = valP;
340}
341
342
343
344xmlrpc_value *
345xmlrpc_int_new(xmlrpc_env * const envP,
346 xmlrpc_int32 const value) {
347
348 xmlrpc_value * valP;
349
350 xmlrpc_createXmlrpcValue(envP, &valP);
351
352 if (!envP->fault_occurred) {
353 valP->_type = XMLRPC_TYPE_INT;
354 valP->_value.i = value;
355 }
356 return valP;
357}
358
359
360
361xmlrpc_value *
362xmlrpc_i8_new(xmlrpc_env * const envP,
363 xmlrpc_int64 const value) {
364
365 xmlrpc_value * valP;
366
367 xmlrpc_createXmlrpcValue(envP, &valP);
368
369 if (!envP->fault_occurred) {
370 valP->_type = XMLRPC_TYPE_I8;
371 valP->_value.i8 = value;
372 }
373 return valP;
374}
375
376
377
378xmlrpc_value *
379xmlrpc_bool_new(xmlrpc_env * const envP,
380 xmlrpc_bool const value) {
381
382 xmlrpc_value * valP;
383
384 xmlrpc_createXmlrpcValue(envP, &valP);
385
386 if (!envP->fault_occurred) {
387 valP->_type = XMLRPC_TYPE_BOOL;
388 valP->_value.b = value;
389 }
390 return valP;
391}
392
393
394
395xmlrpc_value *
396xmlrpc_double_new(xmlrpc_env * const envP,
397 double const value) {
398
399 xmlrpc_value * valP;
400
401 xmlrpc_createXmlrpcValue(envP, &valP);
402
403 if (!envP->fault_occurred) {
404 valP->_type = XMLRPC_TYPE_DOUBLE;
405 valP->_value.d = value;
406 }
407 return valP;
408}
409
410
411
412xmlrpc_value *
413xmlrpc_base64_new(xmlrpc_env * const envP,
414 size_t const length,
415 const unsigned char * const value) {
416
417 xmlrpc_value * valP;
418
419 xmlrpc_createXmlrpcValue(envP, &valP);
420
421 if (!envP->fault_occurred) {
422 valP->_type = XMLRPC_TYPE_BASE64;
423
424 xmlrpc_mem_block_init(envP, &valP->_block, length);
425 if (!envP->fault_occurred) {
426 char * const contents =
427 xmlrpc_mem_block_contents(&valP->_block);
428 memcpy(contents, value, length);
429 }
430 if (envP->fault_occurred)
431 free(valP);
432 }
433 return valP;
434}
435
436
437
438/* array stuff is in xmlrpc_array.c */
439
440
441
442xmlrpc_value *
443xmlrpc_cptr_new(xmlrpc_env * const envP,
444 void * const value) {
445
446 return xmlrpc_cptr_new_dtor(envP, value, NULL((void*)0), NULL((void*)0));
447}
448
449
450
451xmlrpc_value *
452xmlrpc_cptr_new_dtor(xmlrpc_env * const envP,
453 void * const value,
454 xmlrpc_cptr_dtor_fn const dtor,
455 void * const dtorContext) {
456
457 xmlrpc_value * valP;
458
459 xmlrpc_createXmlrpcValue(envP, &valP);
460
461 if (!envP->fault_occurred) {
462 valP->_type = XMLRPC_TYPE_C_PTR;
463 valP->_value.cptr.objectP = value;
464 valP->_value.cptr.dtor = dtor;
465 valP->_value.cptr.dtorContext = dtorContext;
466 }
467 return valP;
468}
469
470
471
472xmlrpc_value *
473xmlrpc_nil_new(xmlrpc_env * const envP) {
474 xmlrpc_value * valP;
475
476 xmlrpc_createXmlrpcValue(envP, &valP);
477 if (!envP->fault_occurred)
478 valP->_type = XMLRPC_TYPE_NIL;
479
480 return valP;
481}
482
483
484
485/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
486** Copyright (C) 2001 by Eric Kidd. All rights reserved.
487**
488** Redistribution and use in source and binary forms, with or without
489** modification, are permitted provided that the following conditions
490** are met:
491** 1. Redistributions of source code must retain the above copyright
492** notice, this list of conditions and the following disclaimer.
493** 2. Redistributions in binary form must reproduce the above copyright
494** notice, this list of conditions and the following disclaimer in the
495** documentation and/or other materials provided with the distribution.
496** 3. The name of the author may not be used to endorse or promote products
497** derived from this software without specific prior written permission.
498**
499** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
500** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
501** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
502** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
503** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
504** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
505** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
506** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
507** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
508** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
509** SUCH DAMAGE. */