Bug Summary

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

Annotated Source Code

1/* Copyright information is at end of file */
2
3/* Implementation note:
4
5 The printf format specifiers we use appear to be entirely standard,
6 except for the "long long" one, which is %I64 on Windows and %lld
7 everywhere else. We could use the C99 standard macro PRId64 for that,
8 but on at least one 64-bit-long GNU compiler, PRId64 is "ld", which is
9 considered to be incompatible with long long. So we have XMLRPC_PRId64.
10*/
11
12#include "xmlrpc_config.h"
13
14#include <assert.h>
15#include <stddef.h>
16#include <stdarg.h>
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <float.h>
21
22#include "int.h"
23#include "xmlrpc-c/base.h"
24#include "xmlrpc-c/base_int.h"
25#include "xmlrpc-c/string_int.h"
26#include "double.h"
27
28#define CRLF"\015\012" "\015\012"
29#define XML_PROLOGUE"<?xml version=\"1.0\" encoding=\"UTF-8\"?>""\015\012" "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"CRLF"\015\012"
30#define APACHE_URL"http://ws.apache.org/xmlrpc/namespaces/extensions" "http://ws.apache.org/xmlrpc/namespaces/extensions"
31#define XMLNS_APACHE"xmlns:ex=\"" "http://ws.apache.org/xmlrpc/namespaces/extensions"
"\""
"xmlns:ex=\"" APACHE_URL"http://ws.apache.org/xmlrpc/namespaces/extensions" "\""
32
33
34static void
35addString(xmlrpc_env * const envP,
36 xmlrpc_mem_block * const outputP,
37 const char * const string) {
38
39 XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, string, strlen(string))xmlrpc_mem_block_append(envP, outputP, string, sizeof(char) *
(strlen(string)))
;
40}
41
42
43
44static void
45formatOut(xmlrpc_env * const envP,
46 xmlrpc_mem_block * const outputP,
47 const char * const formatString,
48 ...) {
49/*----------------------------------------------------------------------------
50 A lightweight print routine for use with various serialization
51 functions.
52
53 Use this routine only for printing small objects -- it uses a
54 fixed-size internal buffer and returns an error on overflow. In
55 particular, do NOT use this routine to print XML-RPC string values!
56-----------------------------------------------------------------------------*/
57 va_list args;
58 char buffer[128];
59 int rc;
60
61 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_serialize.c", 61); while
(0)
;
62
63 va_start(args, formatString)__builtin_va_start(args, formatString);
64
65 rc = XMLRPC_VSNPRINTFvsnprintf(buffer, sizeof(buffer), formatString, args);
66
67 /* Old vsnprintf() (and Windows) fails with return value -1 if the full
68 string doesn't fit in the buffer. New vsnprintf() puts whatever will
69 fit in the buffer, and returns the length of the full string
70 regardless. For us, this truncation is a failure.
71 */
72
73 if (rc < 0)
74 xmlrpc_faultf(envP, "formatOut() overflowed internal buffer");
75 else {
76 unsigned int const formattedLen = rc;
77
78 if (formattedLen + 1 >= (sizeof(buffer)))
79 xmlrpc_faultf(envP, "formatOut() overflowed internal buffer");
80 else
81 XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, buffer, formattedLen)xmlrpc_mem_block_append(envP, outputP, buffer, sizeof(char) *
(formattedLen))
;
82 }
83 va_end(args)__builtin_va_end(args);
84}
85
86
87
88static void
89assertValidUtf8(const char * const str ATTR_UNUSED__attribute__((__unused__)),
90 size_t const len ATTR_UNUSED__attribute__((__unused__))) {
91/*----------------------------------------------------------------------------
92 Assert that the string 'str' of length 'len' is valid UTF-8.
93-----------------------------------------------------------------------------*/
94#if !defined NDEBUG
95 /* Check the assertion; if it's false, issue a message to
96 Standard Error, but otherwise ignore it.
97 */
98 xmlrpc_env env;
99
100 xmlrpc_env_init(&env);
101 xmlrpc_validate_utf8(&env, str, len);
102 if (env.fault_occurred)
103 fprintf(stderrstderr, "*** xmlrpc-c WARNING ***: %s (%s)\n",
104 "Xmlrpc-c sending corrupted UTF-8 data to network",
105 env.fault_string);
106 xmlrpc_env_clean(&env);
107#endif
108}
109
110
111
112static size_t
113escapedSize(const char * const chars,
114 size_t const len) {
115
116 size_t size;
117 size_t i;
118
119 size = 0;
120 for (i = 0; i < len; ++i) {
121 if (chars[i] == '<')
122 size += 4; /* &lt; */
123 else if (chars[i] == '>')
124 size += 4; /* &gt; */
125 else if (chars[i] == '&')
126 size += 5; /* &amp; */
127 else if (chars[i] == '\r')
128 size += 6; /* &#x0d; */
129 else
130 size += 1;
131 }
132 return size;
133}
134
135
136
137static void
138escapeForXml(xmlrpc_env * const envP,
139 const char * const chars,
140 size_t const len,
141 xmlrpc_mem_block ** const outputPP) {
142/*----------------------------------------------------------------------------
143 Escape & and < in a UTF-8 string so as to make it suitable for the
144 content of an XML element. I.e. turn them into entity references
145 &amp; and &lt;.
146
147 Also change > to &gt;, even though not required for XML, for
148 symmetry.
149
150 &lt; etc. are known in XML as "entity references."
151
152 Also Escape CR as &#x0d; . While raw CR _is_ allowed in the content
153 of an XML element, it has a special meaning -- it means line ending.
154 Our input uses LF for for line endings. Since it also means line ending
155 in XML, we just pass it through to our output like it were a regular
156 character.
157
158 &#x0d; is known in XML as a "character reference."
159
160 We assume chars[] is is ASCII. That isn't right -- we should
161 handle all valid UTF-8. Someday, we must do something more complex
162 and copy over multibyte characters verbatim. (The code here could
163 erroneously find that e.g. the 2nd byte of a UTF-8 character is a
164 CR).
165-----------------------------------------------------------------------------*/
166 xmlrpc_mem_block * outputP;
167 size_t outputSize;
168
169 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_serialize.c", 169); while
(0)
;
170 XMLRPC_ASSERT(chars != NULL)do if (!(chars != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 170); while (0)
;
171
172 assertValidUtf8(chars, len);
173
174 /* Note that in UTF-8, any byte that has high bit of zero is a
175 character all by itself (every byte of a multi-byte UTF-8 character
176 has the high bit set). Also, the Unicode code points < 128 are
177 identical to the ASCII ones.
178 */
179
180 outputSize = escapedSize(chars, len);
181
182 outputP = XMLRPC_MEMBLOCK_NEW(char, envP, outputSize)xmlrpc_mem_block_new((envP), sizeof(char) * (outputSize));
183 if (!envP->fault_occurred) {
184 char * p;
185 size_t i;
186 p = XMLRPC_MEMBLOCK_CONTENTS(char, outputP)((char*) xmlrpc_mem_block_contents(outputP)); /* Start at beginning */
187
188 for (i = 0; i < len; i++) {
189 if (chars[i] == '<') {
190 memcpy(p, "&lt;", 4);
191 p += 4;
192 } else if (chars[i] == '>') {
193 memcpy(p, "&gt;", 4);
194 p += 4;
195 } else if (chars[i] == '&') {
196 memcpy(p, "&amp;", 5);
197 p += 5;
198 } else if (chars[i] == '\r') {
199 memcpy(p, "&#x0d;", 6);
200 p += 6;
201 } else {
202 /* Either a plain character or a LF line delimiter */
203 *p = chars[i];
204 p += 1;
205 }
206 }
207 *outputPP = outputP;
208 assert(p == XMLRPC_MEMBLOCK_CONTENTS(char, outputP) + outputSize)((p == ((char*) xmlrpc_mem_block_contents(outputP)) + outputSize
) ? (void) (0) : __assert_fail ("p == ((char*) xmlrpc_mem_block_contents(outputP)) + outputSize"
, "../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c", 208, __PRETTY_FUNCTION__
))
;
209
210 if (envP->fault_occurred)
211 XMLRPC_MEMBLOCK_FREE(char, outputP)xmlrpc_mem_block_free(outputP);
212 }
213}
214
215
216
217static void
218serializeUtf8MemBlock(xmlrpc_env * const envP,
219 xmlrpc_mem_block * const outputP,
220 xmlrpc_mem_block * const inputP) {
221/*----------------------------------------------------------------------------
222 Append the characters in *inputP to the XML stream in *outputP.
223
224 *inputP contains Unicode characters in UTF-8.
225
226 We assume *inputP ends with a NUL character that marks end of
227 string, and we ignore that. (There might also be NUL characters
228 inside the string, though).
229-----------------------------------------------------------------------------*/
230 xmlrpc_mem_block * escapedP;
231
232 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_serialize.c", 232); while
(0)
;
233 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 233); while (0)
;
234 XMLRPC_ASSERT(inputP != NULL)do if (!(inputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 234); while (0)
;
235
236 escapeForXml(envP,
237 XMLRPC_MEMBLOCK_CONTENTS(const char, inputP)((const char*) xmlrpc_mem_block_contents(inputP)),
238 XMLRPC_MEMBLOCK_SIZE(const char, inputP)(xmlrpc_mem_block_size(inputP) / sizeof(const char)) - 1,
239 /* -1 is for the terminating NUL */
240 &escapedP);
241 if (!envP->fault_occurred) {
242 const char * const contents =
243 XMLRPC_MEMBLOCK_CONTENTS(const char, escapedP)((const char*) xmlrpc_mem_block_contents(escapedP));
244 size_t const size = XMLRPC_MEMBLOCK_SIZE(char, escapedP)(xmlrpc_mem_block_size(escapedP) / sizeof(char));
245
246 XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size)xmlrpc_mem_block_append(envP, outputP, contents, sizeof(char)
* (size))
;
247
248 XMLRPC_MEMBLOCK_FREE(const char, escapedP)xmlrpc_mem_block_free(escapedP);
249 }
250}
251
252
253
254static void
255xmlrpc_serialize_base64_data(xmlrpc_env * const envP,
256 xmlrpc_mem_block * const output,
257 unsigned char * const data,
258 size_t const len) {
259/*----------------------------------------------------------------------------
260 Encode the 'len' bytes at 'data' in base64 ASCII and append the result to
261 'output'.
262-----------------------------------------------------------------------------*/
263 xmlrpc_mem_block * encoded;
264
265 encoded = xmlrpc_base64_encode(envP, data, len);
266 if (!envP->fault_occurred) {
267 unsigned char * const contents =
268 XMLRPC_MEMBLOCK_CONTENTS(unsigned char, encoded)((unsigned char*) xmlrpc_mem_block_contents(encoded));
269 size_t const size =
270 XMLRPC_MEMBLOCK_SIZE(unsigned char, encoded)(xmlrpc_mem_block_size(encoded) / sizeof(unsigned char));
271
272 XMLRPC_MEMBLOCK_APPEND(char, envP, output, contents, size)xmlrpc_mem_block_append(envP, output, contents, sizeof(char) *
(size))
;
273
274 XMLRPC_MEMBLOCK_FREE(char, encoded)xmlrpc_mem_block_free(encoded);
275 }
276}
277
278
279
280static void
281serializeDatetime(xmlrpc_env * const envP,
282 xmlrpc_mem_block * const outputP,
283 xmlrpc_value * const valueP) {
284/*----------------------------------------------------------------------------
285 Add to *outputP the content of a <value> element to represent
286 the datetime value *valueP. I.e.
287 "<dateTime.iso8601> ... </dateTime.iso8601>".
288-----------------------------------------------------------------------------*/
289
290 addString(envP, outputP, "<dateTime.iso8601>");
291 if (!envP->fault_occurred) {
292 char dtString[64];
293
294 snprintf(dtString, sizeof(dtString),
295 "%u%02u%02uT%02u:%02u:%02u",
296 valueP->_value.dt.Y,
297 valueP->_value.dt.M,
298 valueP->_value.dt.D,
299 valueP->_value.dt.h,
300 valueP->_value.dt.m,
301 valueP->_value.dt.s);
302
303 if (valueP->_value.dt.u != 0) {
304 char usecString[64];
305 assert(valueP->_value.dt.u < 1000000)((valueP->_value.dt.u < 1000000) ? (void) (0) : __assert_fail
("valueP->_value.dt.u < 1000000", "../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 305, __PRETTY_FUNCTION__))
;
306 snprintf(usecString, sizeof(usecString), ".%06u",
307 valueP->_value.dt.u);
308 STRSCAT(dtString, usecString)(__builtin_strncat ((dtString), (usecString), sizeof(dtString
)-strlen(dtString)), *((dtString)+sizeof(dtString)-1) = '\0')
;
309 }
310 addString(envP, outputP, dtString);
311
312 if (!envP->fault_occurred) {
313 addString(envP, outputP, "</dateTime.iso8601>");
314 }
315 }
316}
317
318
319
320static void
321serializeStructMember(xmlrpc_env * const envP,
322 xmlrpc_mem_block * const outputP,
323 xmlrpc_value * const memberKeyP,
324 xmlrpc_value * const memberValueP,
325 xmlrpc_dialect const dialect) {
326
327 addString(envP, outputP, "<member><name>");
328
329 if (!envP->fault_occurred) {
330 serializeUtf8MemBlock(envP, outputP, &memberKeyP->_block);
331
332 if (!envP->fault_occurred) {
333 addString(envP, outputP, "</name>"CRLF"\015\012");
334
335 if (!envP->fault_occurred) {
336 xmlrpc_serialize_value2(envP, outputP, memberValueP, dialect);
337
338 if (!envP->fault_occurred) {
339 addString(envP, outputP, "</member>"CRLF"\015\012");
340 }
341 }
342 }
343 }
344}
345
346
347
348static void
349serializeStruct(xmlrpc_env * const envP,
350 xmlrpc_mem_block * const outputP,
351 xmlrpc_value * const structP,
352 xmlrpc_dialect const dialect) {
353/*----------------------------------------------------------------------------
354 Add to *outputP the content of a <value> element to represent
355 the structure value *valueP. I.e. "<struct> ... </struct>".
356-----------------------------------------------------------------------------*/
357 addString(envP, outputP, "<struct>"CRLF"\015\012");
358 if (!envP->fault_occurred) {
359 unsigned int const size = xmlrpc_struct_size(envP, structP);
360 if (!envP->fault_occurred) {
361 unsigned int i;
362 for (i = 0; i < size && !envP->fault_occurred; ++i) {
363 xmlrpc_value * memberKeyP;
364 xmlrpc_value * memberValueP;
365
366 xmlrpc_struct_get_key_and_value(envP, structP, i,
367 &memberKeyP, &memberValueP);
368 if (!envP->fault_occurred) {
369 serializeStructMember(envP, outputP,
370 memberKeyP, memberValueP, dialect);
371 }
372 }
373 addString(envP, outputP, "</struct>");
374 }
375 }
376}
377
378
379
380static void
381serializeArray(xmlrpc_env * const envP,
382 xmlrpc_mem_block * const outputP,
383 xmlrpc_value * const valueP,
384 xmlrpc_dialect const dialect) {
385/*----------------------------------------------------------------------------
386 Add to *outputP the content of a <value> element to represent
387 the array value *valueP. I.e. "<array> ... </array>".
388-----------------------------------------------------------------------------*/
389 int const size = xmlrpc_array_size(envP, valueP);
390
391 if (!envP->fault_occurred) {
392 addString(envP, outputP, "<array><data>"CRLF"\015\012");
393 if (!envP->fault_occurred) {
394 int i;
395 /* Serialize each item. */
396 for (i = 0; i < size && !envP->fault_occurred; ++i) {
397 xmlrpc_value * const itemP =
398 xmlrpc_array_get_item(envP, valueP, i);
399 if (!envP->fault_occurred) {
400 xmlrpc_serialize_value2(envP, outputP, itemP, dialect);
401 if (!envP->fault_occurred)
402 addString(envP, outputP, CRLF"\015\012");
403 }
404 }
405 }
406 }
407 if (!envP->fault_occurred)
408 addString(envP, outputP, "</data></array>");
409}
410
411
412
413static void
414formatValueContent(xmlrpc_env * const envP,
415 xmlrpc_mem_block * const outputP,
416 xmlrpc_value * const valueP,
417 xmlrpc_dialect const dialect) {
418/*----------------------------------------------------------------------------
419 Add to *outputP the content of a <value> element to represent
420 value *valueP. E.g. "<int>42</int>"
421-----------------------------------------------------------------------------*/
422 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_serialize.c", 422); while
(0)
;
423
424 switch (valueP->_type) {
425 case XMLRPC_TYPE_INT:
426 formatOut(envP, outputP, "<i4>%d</i4>", valueP->_value.i);
427 break;
428
429 case XMLRPC_TYPE_I8: {
430 const char * const elemName =
431 dialect == xmlrpc_dialect_apache ? "ex:i8" : "i8";
432 formatOut(envP, outputP, "<%s>%" PRId64"l" "d" "</%s>",
433 elemName, valueP->_value.i8, elemName);
434 } break;
435
436 case XMLRPC_TYPE_BOOL:
437 formatOut(envP, outputP, "<boolean>%s</boolean>",
438 valueP->_value.b ? "1" : "0");
439 break;
440
441 case XMLRPC_TYPE_DOUBLE: {
442 const char * serializedValue;
443 xmlrpc_formatFloat(envP, valueP->_value.d, &serializedValue);
444 if (!envP->fault_occurred) {
445 addString(envP, outputP, "<double>");
446 if (!envP->fault_occurred) {
447 addString(envP, outputP, serializedValue);
448 if (!envP->fault_occurred)
449 addString(envP, outputP, "</double>");
450 }
451 xmlrpc_strfree(serializedValue);
452 }
453 } break;
454
455 case XMLRPC_TYPE_DATETIME:
456 serializeDatetime(envP, outputP, valueP);
457 break;
458
459 case XMLRPC_TYPE_STRING:
460 addString(envP, outputP, "<string>");
461 if (!envP->fault_occurred) {
462 serializeUtf8MemBlock(envP, outputP, &valueP->_block);
463 if (!envP->fault_occurred)
464 addString(envP, outputP, "</string>");
465 }
466 break;
467
468 case XMLRPC_TYPE_BASE64: {
469 unsigned char * const contents =
470 XMLRPC_MEMBLOCK_CONTENTS(unsigned char, &valueP->_block)((unsigned char*) xmlrpc_mem_block_contents(&valueP->_block
))
;
471 size_t const size =
472 XMLRPC_MEMBLOCK_SIZE(unsigned char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(unsigned
char))
;
473 addString(envP, outputP, "<base64>"CRLF"\015\012");
474 if (!envP->fault_occurred) {
475 xmlrpc_serialize_base64_data(envP, outputP, contents, size);
476 if (!envP->fault_occurred)
477 addString(envP, outputP, "</base64>");
478 }
479 } break;
480
481 case XMLRPC_TYPE_ARRAY:
482 serializeArray(envP, outputP, valueP, dialect);
483 break;
484
485 case XMLRPC_TYPE_STRUCT:
486 serializeStruct(envP, outputP, valueP, dialect);
487 break;
488
489 case XMLRPC_TYPE_C_PTR:
490 xmlrpc_faultf(envP, "Tried to serialize a C pointer value.");
491 break;
492
493 case XMLRPC_TYPE_NIL: {
494 const char * const elemName =
495 dialect == xmlrpc_dialect_apache ? "ex:nil" : "nil";
496 formatOut(envP, outputP, "<%s/>", elemName);
497 } break;
498
499 case XMLRPC_TYPE_DEAD:
500 xmlrpc_faultf(envP, "Tried to serialize a dead value.");
501 break;
502
503 default:
504 xmlrpc_faultf(envP, "Invalid xmlrpc_value type: %d", valueP->_type);
505 }
506}
507
508
509
510void
511xmlrpc_serialize_value2(xmlrpc_env * const envP,
512 xmlrpc_mem_block * const outputP,
513 xmlrpc_value * const valueP,
514 xmlrpc_dialect const dialect) {
515/*----------------------------------------------------------------------------
516 Generate the XML to represent XML-RPC value 'valueP' in XML-RPC.
517
518 Add it to *outputP.
519-----------------------------------------------------------------------------*/
520 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_serialize.c", 520); while
(0)
;
521 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 521); while (0)
;
522 XMLRPC_ASSERT_VALUE_OK(valueP)do if (!((valueP) != ((void*)0) && (valueP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 522); while (0)
;
523
524 addString(envP, outputP, "<value>");
525
526 if (!envP->fault_occurred) {
527 formatValueContent(envP, outputP, valueP, dialect);
528
529 if (!envP->fault_occurred)
530 addString(envP, outputP, "</value>");
531 }
532}
533
534
535
536void
537xmlrpc_serialize_value(xmlrpc_env * const envP,
538 xmlrpc_mem_block * const outputP,
539 xmlrpc_value * const valueP) {
540
541 xmlrpc_serialize_value2(envP, outputP, valueP, xmlrpc_dialect_i8);
542}
543
544
545
546void
547xmlrpc_serialize_params2(xmlrpc_env * const envP,
548 xmlrpc_mem_block * const outputP,
549 xmlrpc_value * const paramArrayP,
550 xmlrpc_dialect const dialect) {
551/*----------------------------------------------------------------------------
552 Serialize the parameter list of an XML-RPC call.
553-----------------------------------------------------------------------------*/
554 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_serialize.c", 554); while
(0)
;
555 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 555); while (0)
;
556 XMLRPC_ASSERT_VALUE_OK(paramArrayP)do if (!((paramArrayP) != ((void*)0) && (paramArrayP)
->_type != XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 556); while (0)
;
557
558 addString(envP, outputP, "<params>"CRLF"\015\012");
559 if (!envP->fault_occurred) {
560 /* Serialize each parameter. */
561 int const paramCount = xmlrpc_array_size(envP, paramArrayP);
562 if (!envP->fault_occurred) {
563 int paramSeq;
564 for (paramSeq = 0;
565 paramSeq < paramCount && !envP->fault_occurred;
566 ++paramSeq) {
567
568 addString(envP, outputP, "<param>");
569 if (!envP->fault_occurred) {
570 xmlrpc_value * const itemP =
571 xmlrpc_array_get_item(envP, paramArrayP, paramSeq);
572 if (!envP->fault_occurred) {
573 xmlrpc_serialize_value2(envP, outputP, itemP, dialect);
574 if (!envP->fault_occurred)
575 addString(envP, outputP, "</param>"CRLF"\015\012");
576 }
577 }
578 }
579 }
580 }
581
582 if (!envP->fault_occurred)
583 addString(envP, outputP, "</params>"CRLF"\015\012");
584}
585
586
587
588void
589xmlrpc_serialize_params(xmlrpc_env * const envP,
590 xmlrpc_mem_block * const outputP,
591 xmlrpc_value * const paramArrayP) {
592/*----------------------------------------------------------------------------
593 Serialize the parameter list of an XML-RPC call in the original
594 "i8" dialect.
595-----------------------------------------------------------------------------*/
596 xmlrpc_serialize_params2(envP, outputP, paramArrayP, xmlrpc_dialect_i8);
597}
598
599
600
601/*=========================================================================
602** xmlrpc_serialize_call
603**=========================================================================
604** Serialize an XML-RPC call.
605*/
606
607void
608xmlrpc_serialize_call2(xmlrpc_env * const envP,
609 xmlrpc_mem_block * const outputP,
610 const char * const methodName,
611 xmlrpc_value * const paramArrayP,
612 xmlrpc_dialect const dialect) {
613/*----------------------------------------------------------------------------
614 Serialize an XML-RPC call of method named 'methodName' with parameter
615 list *paramArrayP. Use XML-RPC dialect 'dialect'.
616
617 Append the call XML ot *outputP.
618-----------------------------------------------------------------------------*/
619 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_serialize.c", 619); while
(0)
;
620 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 620); while (0)
;
621 XMLRPC_ASSERT(methodName != NULL)do if (!(methodName != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 621); while (0)
;
622 XMLRPC_ASSERT_VALUE_OK(paramArrayP)do if (!((paramArrayP) != ((void*)0) && (paramArrayP)
->_type != XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 622); while (0)
;
623
624 addString(envP, outputP, XML_PROLOGUE"<?xml version=\"1.0\" encoding=\"UTF-8\"?>""\015\012");
625 if (!envP->fault_occurred) {
626 const char * const xmlns =
627 dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE"xmlns:ex=\"" "http://ws.apache.org/xmlrpc/namespaces/extensions"
"\""
: "";
628 formatOut(envP, outputP, "<methodCall%s>"CRLF"\015\012""<methodName>", xmlns);
629 if (!envP->fault_occurred) {
630 xmlrpc_mem_block * encodedP;
631 escapeForXml(envP, methodName, strlen(methodName), &encodedP);
632 if (!envP->fault_occurred) {
633 const char * const contents =
634 XMLRPC_MEMBLOCK_CONTENTS(char, encodedP)((char*) xmlrpc_mem_block_contents(encodedP));
635 size_t const size = XMLRPC_MEMBLOCK_SIZE(char, encodedP)(xmlrpc_mem_block_size(encodedP) / sizeof(char));
636 XMLRPC_MEMBLOCK_APPEND(char, envP, outputP, contents, size)xmlrpc_mem_block_append(envP, outputP, contents, sizeof(char)
* (size))
;
637 if (!envP->fault_occurred) {
638 addString(envP, outputP, "</methodName>"CRLF"\015\012");
639 if (!envP->fault_occurred) {
640 xmlrpc_serialize_params2(envP, outputP, paramArrayP,
641 dialect);
642 if (!envP->fault_occurred)
643 addString(envP, outputP, "</methodCall>"CRLF"\015\012");
644 }
645 }
646 XMLRPC_MEMBLOCK_FREE(char, encodedP)xmlrpc_mem_block_free(encodedP);
647 }
648 }
649 }
650}
651
652
653
654void
655xmlrpc_serialize_call(xmlrpc_env * const envP,
656 xmlrpc_mem_block * const outputP,
657 const char * const methodName,
658 xmlrpc_value * const paramArrayP) {
659
660 xmlrpc_serialize_call2(envP, outputP, methodName, paramArrayP,
661 xmlrpc_dialect_i8);
662}
663
664
665
666void
667xmlrpc_serialize_response2(xmlrpc_env * const envP,
668 xmlrpc_mem_block * const outputP,
669 xmlrpc_value * const valueP,
670 xmlrpc_dialect const dialect) {
671/*----------------------------------------------------------------------------
672 Serialize a result response to an XML-RPC call.
673
674 The result is 'valueP'.
675
676 Add the response XML to *outputP.
677-----------------------------------------------------------------------------*/
678 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_serialize.c", 678); while
(0)
;
679 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 679); while (0)
;
680 XMLRPC_ASSERT_VALUE_OK(valueP)do if (!((valueP) != ((void*)0) && (valueP)->_type
!= XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 680); while (0)
;
681
682 addString(envP, outputP, XML_PROLOGUE"<?xml version=\"1.0\" encoding=\"UTF-8\"?>""\015\012");
683 if (!envP->fault_occurred) {
684 const char * const xmlns =
685 dialect == xmlrpc_dialect_apache ? " " XMLNS_APACHE"xmlns:ex=\"" "http://ws.apache.org/xmlrpc/namespaces/extensions"
"\""
: "";
686 formatOut(envP, outputP,
687 "<methodResponse%s>"CRLF"\015\012""<params>"CRLF"\015\012""<param>", xmlns);
688 if (!envP->fault_occurred) {
689 xmlrpc_serialize_value2(envP, outputP, valueP, dialect);
690 if (!envP->fault_occurred) {
691 addString(envP, outputP,
692 "</param>"CRLF"\015\012""</params>"CRLF"\015\012"
693 "</methodResponse>"CRLF"\015\012");
694 }
695 }
696 }
697}
698
699
700
701void
702xmlrpc_serialize_response(xmlrpc_env * const envP,
703 xmlrpc_mem_block * const outputP,
704 xmlrpc_value * const valueP) {
705
706 xmlrpc_serialize_response2(envP, outputP, valueP, xmlrpc_dialect_i8);
707}
708
709
710
711void
712xmlrpc_serialize_fault(xmlrpc_env * const envP,
713 xmlrpc_mem_block * const outputP,
714 const xmlrpc_env * const faultP) {
715/*----------------------------------------------------------------------------
716 Serialize a fault response to an XML-RPC call.
717
718 'faultP' is the fault.
719
720 Add the response XML to *outputP.
721-----------------------------------------------------------------------------*/
722 xmlrpc_value * faultStructP;
723
724 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_serialize.c", 724); while
(0)
;
725 XMLRPC_ASSERT(outputP != NULL)do if (!(outputP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 725); while (0)
;
726 XMLRPC_ASSERT(faultP != NULL)do if (!(faultP != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c"
, 726); while (0)
;
1
Within the expansion of the macro 'XMLRPC_ASSERT':
a
Assuming 'faultP' is equal to null
727 XMLRPC_ASSERT(faultP->fault_occurred)do if (!(faultP->fault_occurred)) xmlrpc_assertion_failed(
"../../../../libs/xmlrpc-c/src/xmlrpc_serialize.c", 727); while
(0)
;
2
Within the expansion of the macro 'XMLRPC_ASSERT':
a
Access to field 'fault_occurred' results in a dereference of a null pointer (loaded from variable 'faultP')
728
729 faultStructP = xmlrpc_build_value(envP, "{s:i,s:s}",
730 "faultCode",
731 (xmlrpc_int32) faultP->fault_code,
732 "faultString", faultP->fault_string);
733 if (!envP->fault_occurred) {
734 addString(envP, outputP, XML_PROLOGUE"<?xml version=\"1.0\" encoding=\"UTF-8\"?>""\015\012");
735 if (!envP->fault_occurred) {
736 addString(envP, outputP, "<methodResponse>"CRLF"\015\012""<fault>"CRLF"\015\012");
737 if (!envP->fault_occurred) {
738 xmlrpc_serialize_value(envP, outputP, faultStructP);
739 if (!envP->fault_occurred) {
740 addString(envP, outputP,
741 CRLF"\015\012""</fault>"CRLF"\015\012""</methodResponse>"CRLF"\015\012");
742 }
743 }
744 }
745 xmlrpc_DECREF(faultStructP);
746 }
747}
748
749
750
751/* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
752**
753** Redistribution and use in source and binary forms, with or without
754** modification, are permitted provided that the following conditions
755** are met:
756** 1. Redistributions of source code must retain the above copyright
757** notice, this list of conditions and the following disclaimer.
758** 2. Redistributions in binary form must reproduce the above copyright
759** notice, this list of conditions and the following disclaimer in the
760** documentation and/or other materials provided with the distribution.
761** 3. The name of the author may not be used to endorse or promote products
762** derived from this software without specific prior written permission.
763**
764** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
765** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
766** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
767** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
768** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
769** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
770** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
771** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
772** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
773** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
774** SUCH DAMAGE. */