File: | src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_data.c |
Location: | line 433, column 5 |
Description: | Use of memory after it is freed |
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 | ||||
18 | static void | |||
19 | destroyCptr(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 | ||||
28 | static void | |||
29 | destroyValue(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 | ||||
96 | void | |||
97 | xmlrpc_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 | ||||
107 | void | |||
108 | xmlrpc_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); | |||
111 | XMLRPC_ASSERT(valueP->_refcount > 0)do if (!(valueP->_refcount > 0)) xmlrpc_assertion_failed ("../../../../libs/xmlrpc-c/src/xmlrpc_data.c", 111); while ( 0); | |||
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 | ||||
127 | const char * | |||
128 | xmlrpc_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 | ||||
151 | static void | |||
152 | validateType(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 | ||||
175 | void | |||
176 | xmlrpc_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 | ||||
187 | void | |||
188 | xmlrpc_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 | ||||
199 | void | |||
200 | xmlrpc_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 | ||||
218 | void | |||
219 | xmlrpc_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 | ||||
248 | void | |||
249 | xmlrpc_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 | ||||
265 | void | |||
266 | xmlrpc_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 | ||||
277 | void | |||
278 | xmlrpc_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 | ||||
289 | void | |||
290 | xmlrpc_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 | ||||
302 | void | |||
303 | xmlrpc_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 | ||||
314 | xmlrpc_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 | ||||
322 | void | |||
323 | xmlrpc_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 | ||||
344 | xmlrpc_value * | |||
345 | xmlrpc_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 | ||||
361 | xmlrpc_value * | |||
362 | xmlrpc_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 | ||||
378 | xmlrpc_value * | |||
379 | xmlrpc_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 | ||||
395 | xmlrpc_value * | |||
396 | xmlrpc_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 | ||||
412 | xmlrpc_value * | |||
413 | xmlrpc_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 | ||||
442 | xmlrpc_value * | |||
443 | xmlrpc_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 | ||||
451 | xmlrpc_value * | |||
452 | xmlrpc_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 | ||||
472 | xmlrpc_value * | |||
473 | xmlrpc_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. */ |