Bug Summary

File:src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_struct.c
Location:line 581, column 18
Description:Dereference of null pointer (loaded from variable 'keyvalP')

Annotated Source Code

1#include "xmlrpc_config.h"
2
3#include <assert.h>
4#include <stddef.h>
5#include <stdlib.h>
6#include <string.h>
7
8#include "xmlrpc-c/base.h"
9#include "xmlrpc-c/base_int.h"
10#include "int.h"
11
12#define KEY_ERROR_BUFFER_SZ(32) (32)
13
14
15void
16xmlrpc_destroyStruct(xmlrpc_value * const structP) {
17
18 _struct_member * const members =
19 XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block)((_struct_member*) xmlrpc_mem_block_contents(&structP->
_block))
;
20 size_t const size =
21 XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block)(xmlrpc_mem_block_size(&structP->_block) / sizeof(_struct_member
))
;
22
23 unsigned int i;
24
25 for (i = 0; i < size; ++i) {
26 xmlrpc_DECREF(members[i].key);
27 xmlrpc_DECREF(members[i].value);
28 }
29 XMLRPC_MEMBLOCK_CLEAN(_struct_member, &structP->_block)xmlrpc_mem_block_clean(&structP->_block);
30}
31
32
33
34/*=========================================================================
35** xmlrpc_struct_new
36**=========================================================================
37** Create a new <struct> value. The corresponding destructor code
38** currently lives in xmlrpc_DECREF.
39**
40** We store the individual members in an array of _struct_member. This
41** contains a key, a hash code, and a value. We look up keys by doing
42** a linear search of the hash codes.
43*/
44
45xmlrpc_value *
46xmlrpc_struct_new(xmlrpc_env * const envP) {
47
48 xmlrpc_value * valP;
49
50 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 50); while (
0)
;
51
52 xmlrpc_createXmlrpcValue(envP, &valP);
53 if (!envP->fault_occurred) {
54 valP->_type = XMLRPC_TYPE_STRUCT;
55
56 XMLRPC_MEMBLOCK_INIT(_struct_member, envP, &valP->_block, 0)xmlrpc_mem_block_init((envP), (&valP->_block), sizeof(
_struct_member) * (0))
;
57
58 if (envP->fault_occurred)
59 free(valP);
60 }
61 return valP;
62}
63
64
65
66/*=========================================================================
67** xmlrpc_struct_size
68**=========================================================================
69** Return the number of key-value pairs contained in the struct. If the
70** value is not a struct, return -1 and set a fault.
71*/
72
73int
74xmlrpc_struct_size(xmlrpc_env * const envP,
75 xmlrpc_value * const structP) {
76
77 int retval;
78
79 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 79); while (
0)
;
80 XMLRPC_ASSERT_VALUE_OK(structP)do if (!((structP) != ((void*)0) && (structP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 80); while (0)
;
81
82 if (structP->_type != XMLRPC_TYPE_STRUCT) {
83 xmlrpc_env_set_fault_formatted(
84 envP, XMLRPC_TYPE_ERROR(-501), "Value is not a struct. It is type #%d",
85 structP->_type);
86 retval = -1;
87 } else {
88 size_t const size =
89 XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block)(xmlrpc_mem_block_size(&structP->_block) / sizeof(_struct_member
))
;
90
91 assert((size_t)(int)size == size)(((size_t)(int)size == size) ? (void) (0) : __assert_fail ("(size_t)(int)size == size"
, "../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 91, __PRETTY_FUNCTION__
))
;
92 /* Because structs are defined to have few enough members */
93
94 retval = (int)size;
95 }
96 return retval;
97}
98
99
100
101static uint32_t
102hashStructKey(const char * const key,
103 size_t const keyLen) {
104
105 uint32_t hash;
106 size_t i;
107
108 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 108); while (0)
;
109
110 /* This is the Bernstein hash, optimized for lower case ASCII
111 keys. Note that the bytes of such a key differ only in their
112 lower 5 bits.
113 */
114 for (hash = 0, i = 0; i < keyLen; ++i)
115 hash = hash + key[i] + (hash << 5);
116
117 return hash;
118}
119
120
121
122/*=========================================================================
123** find_member
124**=========================================================================
125** Get the index of the member with the specified key, or -1 if no such
126** member exists.
127*/
128
129static int
130find_member(xmlrpc_value * const strctP,
131 const char * const key,
132 size_t const keyLen) {
133
134 int retval;
135 size_t size, i;
136 uint32_t searchHash;
137 _struct_member * contents; /* array */
138 bool found;
139 size_t foundIndex; /* Meaningful only when 'found' is true */
140
141 XMLRPC_ASSERT_VALUE_OK(strctP)do if (!((strctP) != ((void*)0) && (strctP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 141); while (0)
;
142 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 142); while (0)
;
143 foundIndex = 0; /* defeat used-before-set compiler warning */
144
145 /* Look for our key. */
146 searchHash = hashStructKey(key, keyLen);
147 size = XMLRPC_MEMBLOCK_SIZE(_struct_member, &strctP->_block)(xmlrpc_mem_block_size(&strctP->_block) / sizeof(_struct_member
))
;
148 contents = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block)((_struct_member*) xmlrpc_mem_block_contents(&strctP->
_block))
;
149 for (i = 0, found = false; i < size && !found; ++i) {
150 if (contents[i].keyHash == searchHash) {
151 xmlrpc_value * const keyvalP = contents[i].key;
152 const char * const keystr =
153 XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block)((char*) xmlrpc_mem_block_contents(&keyvalP->_block));
154 size_t const keystrSize =
155 XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block)(xmlrpc_mem_block_size(&keyvalP->_block) / sizeof(char
))
-1;
156 if (keystrSize == keyLen && memcmp(key, keystr, keyLen) == 0) {
157 found = true;
158 foundIndex = i;
159 }
160 }
161 }
162 if (found) {
163 assert((size_t)(int)foundIndex == foundIndex)(((size_t)(int)foundIndex == foundIndex) ? (void) (0) : __assert_fail
("(size_t)(int)foundIndex == foundIndex", "../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 163, __PRETTY_FUNCTION__))
;
164 /* Definition of structure says it has few enough members */
165 retval = foundIndex;
166 } else
167 retval = -1;
168
169 return retval;
170}
171
172
173
174/*=========================================================================
175** xmlrpc_struct_has_key
176**=========================================================================
177*/
178
179int
180xmlrpc_struct_has_key(xmlrpc_env * const envP,
181 xmlrpc_value * const strctP,
182 const char * const key) {
183
184 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 184); while (0)
;
185 return xmlrpc_struct_has_key_n(envP, strctP, key, strlen(key));
186}
187
188
189
190int
191xmlrpc_struct_has_key_n(xmlrpc_env * const envP,
192 xmlrpc_value * const strctP,
193 const char * const key,
194 size_t const key_len) {
195 int index;
196
197 /* Suppress a compiler warning about uninitialized variables. */
198 index = 0;
199
200 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 200); while
(0)
;
201 XMLRPC_ASSERT_VALUE_OK(strctP)do if (!((strctP) != ((void*)0) && (strctP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 201); while (0)
;
202 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 202); while (0)
;
203
204 XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT)do if ((strctP)->_type != (XMLRPC_TYPE_STRUCT)) do { xmlrpc_env_set_fault
((envP),((-501)),("Expected " "XMLRPC_TYPE_STRUCT")); goto cleanup
; } while (0); while (0)
;
205 index = find_member(strctP, key, key_len);
206
207 cleanup:
208 if (envP->fault_occurred)
209 return 0;
210 return (index >= 0);
211}
212
213
214
215/*=========================================================================
216** xmlrpc_struct_find_value...
217**=========================================================================
218** These functions look up a specified key value in a specified struct.
219** If it exists, they return the value of the struct member. If not,
220** they return a NULL to indicate such.
221*/
222
223/* It would be a nice extension to be able to look up a key that is
224 not a text string.
225*/
226
227void
228xmlrpc_struct_find_value(xmlrpc_env * const envP,
229 xmlrpc_value * const structP,
230 const char * const key,
231 xmlrpc_value ** const valuePP) {
232/*----------------------------------------------------------------------------
233 Given a key, retrieve a value from the struct. If the key is not
234 present, return NULL as *valuePP.
235-----------------------------------------------------------------------------*/
236 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 236); while
(0)
;
237 XMLRPC_ASSERT_VALUE_OK(structP)do if (!((structP) != ((void*)0) && (structP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 237); while (0)
;
238 XMLRPC_ASSERT_PTR_OK(key)do if (!((key) != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 238); while (0)
;
239
240 if (structP->_type != XMLRPC_TYPE_STRUCT)
241 xmlrpc_env_set_fault_formatted(
242 envP, XMLRPC_TYPE_ERROR(-501), "Value is not a struct. It is type #%d",
243 structP->_type);
244 else {
245 int index;
246
247 /* Get our member index. */
248 index = find_member(structP, key, strlen(key));
249 if (index < 0)
250 *valuePP = NULL((void*)0);
251 else {
252 _struct_member * const members =
253 XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block)((_struct_member*) xmlrpc_mem_block_contents(&structP->
_block))
;
254 *valuePP = members[index].value;
255
256 XMLRPC_ASSERT_VALUE_OK(*valuePP)do if (!((*valuePP) != ((void*)0) && (*valuePP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 256); while (0)
;
257
258 xmlrpc_INCREF(*valuePP);
259 }
260 }
261}
262
263
264
265void
266xmlrpc_struct_find_value_v(xmlrpc_env * const envP,
267 xmlrpc_value * const structP,
268 xmlrpc_value * const keyP,
269 xmlrpc_value ** const valuePP) {
270/*----------------------------------------------------------------------------
271 Given a key, retrieve a value from the struct. If the key is not
272 present, return NULL as *valuePP.
273-----------------------------------------------------------------------------*/
274 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 274); while
(0)
;
275 XMLRPC_ASSERT_VALUE_OK(structP)do if (!((structP) != ((void*)0) && (structP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 275); while (0)
;
276 XMLRPC_ASSERT_VALUE_OK(keyP)do if (!((keyP) != ((void*)0) && (keyP)->_type != XMLRPC_TYPE_DEAD
)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 276); while (0)
;
277
278 if (structP->_type != XMLRPC_TYPE_STRUCT)
279 xmlrpc_env_set_fault_formatted(
280 envP, XMLRPC_TYPE_ERROR(-501), "Value is not a struct. It is type #%d",
281 structP->_type);
282 else {
283 if (keyP->_type != XMLRPC_TYPE_STRING)
284 xmlrpc_env_set_fault_formatted(
285 envP, XMLRPC_TYPE_ERROR(-501), "Key value is not a string. "
286 "It is type #%d",
287 keyP->_type);
288 else {
289 int index;
290
291 /* Get our member index. */
292 index = find_member(structP,
293 XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block)((char*) xmlrpc_mem_block_contents(&keyP->_block)),
294 XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block)(xmlrpc_mem_block_size(&keyP->_block) / sizeof(char))-1);
295 if (index < 0)
296 *valuePP = NULL((void*)0);
297 else {
298 _struct_member * const members =
299 XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block)((_struct_member*) xmlrpc_mem_block_contents(&structP->
_block))
;
300 *valuePP = members[index].value;
301
302 XMLRPC_ASSERT_VALUE_OK(*valuePP)do if (!((*valuePP) != ((void*)0) && (*valuePP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 302); while (0)
;
303
304 xmlrpc_INCREF(*valuePP);
305 }
306 }
307 }
308}
309
310
311
312/*=========================================================================
313** xmlrpc_struct_read_value...
314**=========================================================================
315** These fail if no member with the specified key exists.
316** Otherwise, they are the same as xmlrpc_struct_find_value...
317*/
318
319void
320xmlrpc_struct_read_value_v(xmlrpc_env * const envP,
321 xmlrpc_value * const structP,
322 xmlrpc_value * const keyP,
323 xmlrpc_value ** const valuePP) {
324
325 xmlrpc_struct_find_value_v(envP, structP, keyP, valuePP);
326
327 if (!envP->fault_occurred) {
328 if (*valuePP == NULL((void*)0)) {
329 xmlrpc_env_set_fault_formatted(
330 envP, XMLRPC_INDEX_ERROR(-502), "No member of struct has key '%.*s'",
331 (int)XMLRPC_MEMBLOCK_SIZE(char, &keyP->_block)(xmlrpc_mem_block_size(&keyP->_block) / sizeof(char)),
332 XMLRPC_MEMBLOCK_CONTENTS(char, &keyP->_block)((char*) xmlrpc_mem_block_contents(&keyP->_block)));
333 }
334 }
335}
336
337
338
339void
340xmlrpc_struct_read_value(xmlrpc_env * const envP,
341 xmlrpc_value * const structP,
342 const char * const key,
343 xmlrpc_value ** const valuePP) {
344
345 xmlrpc_struct_find_value(envP, structP, key, valuePP);
346
347 if (!envP->fault_occurred) {
348 if (*valuePP == NULL((void*)0)) {
349 xmlrpc_env_set_fault_formatted(
350 envP, XMLRPC_INDEX_ERROR(-502), "No member of struct has key '%s'",
351 key);
352 /* We should fix the error message to format the key for display */
353 }
354 }
355}
356
357
358
359/*=========================================================================
360** xmlrpc_struct_get_value...
361**=========================================================================
362** These are for backward compatibility. They used to be the only ones.
363** They're deprecated because they don't acquire a reference to the
364** value they return.
365*/
366
367xmlrpc_value *
368xmlrpc_struct_get_value_n(xmlrpc_env * const envP,
369 xmlrpc_value * const structP,
370 const char * const key,
371 size_t const keyLen) {
372
373 xmlrpc_value * retval;
374 xmlrpc_value * keyP;
375
376 keyP = xmlrpc_build_value(envP, "s#", key, keyLen);
377 if (!envP->fault_occurred) {
378 xmlrpc_struct_find_value_v(envP, structP, keyP, &retval);
379
380 if (!envP->fault_occurred) {
381 if (retval == NULL((void*)0)) {
382 xmlrpc_env_set_fault_formatted(
383 envP, XMLRPC_INDEX_ERROR(-502),
384 "No member of struct has key '%.*s'",
385 (int)keyLen, key);
386 /* We should fix the error message to format the key
387 for display */
388 } else
389 /* For backward compatibility. */
390 xmlrpc_DECREF(retval);
391 }
392 xmlrpc_DECREF(keyP);
393 }
394 return retval;
395}
396
397
398
399xmlrpc_value *
400xmlrpc_struct_get_value(xmlrpc_env * const envP,
401 xmlrpc_value * const strctP,
402 const char * const key) {
403
404 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 404); while (0)
;
405 return xmlrpc_struct_get_value_n(envP, strctP, key, strlen(key));
406}
407
408
409
410/*=========================================================================
411** xmlrpc_struct_set_value
412**=========================================================================
413*/
414
415void
416xmlrpc_struct_set_value(xmlrpc_env * const envP,
417 xmlrpc_value * const strctP,
418 const char * const key,
419 xmlrpc_value * const valueP) {
420
421 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 421); while (0)
;
422 xmlrpc_struct_set_value_n(envP, strctP, key, strlen(key), valueP);
423}
424
425
426
427void
428xmlrpc_struct_set_value_n(xmlrpc_env * const envP,
429 xmlrpc_value * const strctP,
430 const char * const key,
431 size_t const keyLen,
432 xmlrpc_value * const valueP) {
433
434 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 434); while
(0)
;
435 XMLRPC_ASSERT(key != NULL)do if (!(key != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 435); while (0)
;
436
437 if (xmlrpc_value_type(strctP) != XMLRPC_TYPE_STRUCT)
438 xmlrpc_env_set_fault_formatted(
439 envP, XMLRPC_TYPE_ERROR(-501),
440 "Trying to set value in something not a struct. "
441 "Type is %d; struct is %d",
442 xmlrpc_value_type(strctP), XMLRPC_TYPE_STRUCT);
443 else {
444 xmlrpc_value * keyvalP;
445
446 /* Get the key as an xmlrpc_value */
447 keyvalP = xmlrpc_build_value(envP, "s#", key, keyLen);
448 if (!envP->fault_occurred)
449 xmlrpc_struct_set_value_v(envP, strctP, keyvalP, valueP);
450
451 xmlrpc_DECREF(keyvalP);
452 }
453}
454
455
456
457void
458xmlrpc_struct_set_value_v(xmlrpc_env * const envP,
459 xmlrpc_value * const strctP,
460 xmlrpc_value * const keyvalP,
461 xmlrpc_value * const valueP) {
462
463 char *key;
464 size_t key_len;
465 int index;
466 _struct_member *members, *member, new_member;
467 xmlrpc_value *old_value;
468
469 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 469); while
(0)
;
470 XMLRPC_ASSERT_VALUE_OK(strctP)do if (!((strctP) != ((void*)0) && (strctP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 470); while (0)
;
471 XMLRPC_ASSERT_VALUE_OK(keyvalP)do if (!((keyvalP) != ((void*)0) && (keyvalP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 471); while (0)
;
472 XMLRPC_ASSERT_VALUE_OK(valueP)do if (!((valueP) != ((void*)0) && (valueP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 472); while (0)
;
473
474 XMLRPC_TYPE_CHECK(envP, strctP, XMLRPC_TYPE_STRUCT)do if ((strctP)->_type != (XMLRPC_TYPE_STRUCT)) do { xmlrpc_env_set_fault
((envP),((-501)),("Expected " "XMLRPC_TYPE_STRUCT")); goto cleanup
; } while (0); while (0)
;
475 XMLRPC_TYPE_CHECK(envP, keyvalP, XMLRPC_TYPE_STRING)do if ((keyvalP)->_type != (XMLRPC_TYPE_STRING)) do { xmlrpc_env_set_fault
((envP),((-501)),("Expected " "XMLRPC_TYPE_STRING")); goto cleanup
; } while (0); while (0)
;
476
477 key = XMLRPC_MEMBLOCK_CONTENTS(char, &keyvalP->_block)((char*) xmlrpc_mem_block_contents(&keyvalP->_block));
478 key_len = XMLRPC_MEMBLOCK_SIZE(char, &keyvalP->_block)(xmlrpc_mem_block_size(&keyvalP->_block) / sizeof(char
))
- 1;
479 index = find_member(strctP, key, key_len);
480
481 if (index >= 0) {
482 /* Change the value of an existing member. (But be careful--the
483 ** original and new values might be the same object, so watch
484 ** the order of INCREF and DECREF calls!) */
485 members = XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &strctP->_block)((_struct_member*) xmlrpc_mem_block_contents(&strctP->
_block))
;
486 member = &members[index];
487
488 /* Juggle our references. */
489 old_value = member->value;
490 member->value = valueP;
491 xmlrpc_INCREF(member->value);
492 xmlrpc_DECREF(old_value);
493 } else {
494 /* Add a new member. */
495 new_member.keyHash = hashStructKey(key, key_len);
496 new_member.key = keyvalP;
497 new_member.value = valueP;
498 XMLRPC_MEMBLOCK_APPEND(_struct_member, envP, &strctP->_block,xmlrpc_mem_block_append(envP, &strctP->_block, &new_member
, sizeof(_struct_member) * (1))
499 &new_member, 1)xmlrpc_mem_block_append(envP, &strctP->_block, &new_member
, sizeof(_struct_member) * (1))
;
500 XMLRPC_FAIL_IF_FAULT(envP)do { if ((envP)->fault_occurred) goto cleanup; } while (0);
501 xmlrpc_INCREF(keyvalP);
502 xmlrpc_INCREF(valueP);
503 }
504
505cleanup:
506 return;
507}
508
509
510
511/* Note that the order of keys and values is undefined, and may change
512 when you modify the struct.
513*/
514
515void
516xmlrpc_struct_read_member(xmlrpc_env * const envP,
517 xmlrpc_value * const structP,
518 unsigned int const index,
519 xmlrpc_value ** const keyvalP,
520 xmlrpc_value ** const valueP) {
521
522 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 522); while
(0)
;
523 XMLRPC_ASSERT_VALUE_OK(structP)do if (!((structP) != ((void*)0) && (structP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 523); while (0)
;
524 XMLRPC_ASSERT_PTR_OK(keyvalP)do if (!((keyvalP) != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 524); while (0)
;
525 XMLRPC_ASSERT_PTR_OK(valueP)do if (!((valueP) != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 525); while (0)
;
526
527 if (structP->_type != XMLRPC_TYPE_STRUCT)
528 xmlrpc_env_set_fault_formatted(
529 envP, XMLRPC_TYPE_ERROR(-501), "Attempt to read a struct member "
530 "of something that is not a struct");
531 else {
532 _struct_member * const members =
533 XMLRPC_MEMBLOCK_CONTENTS(_struct_member, &structP->_block)((_struct_member*) xmlrpc_mem_block_contents(&structP->
_block))
;
534 size_t const size =
535 XMLRPC_MEMBLOCK_SIZE(_struct_member, &structP->_block)(xmlrpc_mem_block_size(&structP->_block) / sizeof(_struct_member
))
;
536
537 if (index >= size)
538 xmlrpc_env_set_fault_formatted(
539 envP, XMLRPC_INDEX_ERROR(-502), "Index %u is beyond the end of "
540 "the %u-member structure", index, (unsigned int)size);
541 else {
542 _struct_member * const memberP = &members[index];
543 *keyvalP = memberP->key;
544 xmlrpc_INCREF(memberP->key);
545 *valueP = memberP->value;
546 xmlrpc_INCREF(memberP->value);
547 }
548 }
549}
550
551
552
553void
554xmlrpc_struct_get_key_and_value(xmlrpc_env * const envP,
555 xmlrpc_value * const structP,
556 int const index,
557 xmlrpc_value ** const keyvalP,
558 xmlrpc_value ** const valueP) {
559/*----------------------------------------------------------------------------
560 Same as xmlrpc_struct_read_member(), except doesn't take a reference
561 to the returned value.
562
563 This is obsolete.
564-----------------------------------------------------------------------------*/
565 XMLRPC_ASSERT_ENV_OK(envP)do if (!((envP) != ((void*)0) && (envP->fault_string
== ((void*)0)) && !(envP)->fault_occurred)) xmlrpc_assertion_failed
("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c", 565); while
(0)
;
566 XMLRPC_ASSERT_VALUE_OK(structP)do if (!((structP) != ((void*)0) && (structP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 566); while (0)
;
567 XMLRPC_ASSERT_PTR_OK(keyvalP)do if (!((keyvalP) != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 567); while (0)
;
1
Within the expansion of the macro 'XMLRPC_ASSERT_PTR_OK':
a
Assuming 'keyvalP' is equal to null
568 XMLRPC_ASSERT_PTR_OK(valueP)do if (!((valueP) != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_struct.c"
, 568); while (0)
;
569
570 if (index < 0)
2
Assuming 'index' is < 0
3
Taking true branch
571 xmlrpc_env_set_fault_formatted(
572 envP, XMLRPC_INDEX_ERROR(-502), "Index %d is negative.", index);
573 else {
574 xmlrpc_struct_read_member(envP, structP, index, keyvalP, valueP);
575 if (!envP->fault_occurred) {
576 xmlrpc_DECREF(*keyvalP);
577 xmlrpc_DECREF(*valueP);
578 }
579 }
580 if (envP->fault_occurred) {
4
Taking true branch
581 *keyvalP = NULL((void*)0);
5
Dereference of null pointer (loaded from variable 'keyvalP')
582 *valueP = NULL((void*)0);
583 }
584}
585
586
587
588/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
589**
590** Redistribution and use in source and binary forms, with or without
591** modification, are permitted provided that the following conditions
592** are met:
593** 1. Redistributions of source code must retain the above copyright
594** notice, this list of conditions and the following disclaimer.
595** 2. Redistributions in binary form must reproduce the above copyright
596** notice, this list of conditions and the following disclaimer in the
597** documentation and/or other materials provided with the distribution.
598** 3. The name of the author may not be used to endorse or promote products
599** derived from this software without specific prior written permission.
600**
601** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
602** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
603** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
604** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
605** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
606** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
607** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
608** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
609** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
610** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
611** SUCH DAMAGE. */
612