Bug Summary

File:src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_string.c
Location:line 697, column 5
Description:Undefined or garbage value returned to caller

Annotated Source Code

1/*=============================================================================
2 xmlrpc_string
3===============================================================================
4 Routines for the "string" type of xmlrpc_value.
5
6 By Bryan Henderson.
7
8 Contributed to the public domain by its author.
9=============================================================================*/
10
11#include "xmlrpc_config.h"
12
13#include <stddef.h>
14#include <stdlib.h>
15#include <stdarg.h>
16#include <string.h>
17
18#include "bool.h"
19#include "mallocvar.h"
20
21#include "xmlrpc-c/base.h"
22#include "xmlrpc-c/base_int.h"
23#include "xmlrpc-c/string_int.h"
24
25
26
27void
28xmlrpc_destroyString(xmlrpc_value * const valueP) {
29
30 if (valueP->_wcs_block)
31 xmlrpc_mem_block_free(valueP->_wcs_block);
32
33 xmlrpc_mem_block_clean(&valueP->_block);
34}
35
36
37
38static void
39verifyNoNulls(xmlrpc_env * const envP,
40 const char * const contents,
41 unsigned int const len) {
42/*----------------------------------------------------------------------------
43 Verify that the character array 'contents', which is 'len' bytes long,
44 does not contain any NUL characters, which means it can be made into
45 a passable ASCIIZ string just by adding a terminating NUL.
46
47 Fail if the array contains a NUL.
48-----------------------------------------------------------------------------*/
49 unsigned int i;
50
51 for (i = 0; i < len && !envP->fault_occurred; ++i)
52 if (contents[i] == '\0')
53 xmlrpc_env_set_fault_formatted(
54 envP, XMLRPC_TYPE_ERROR(-501),
55 "String must not contain NUL characters");
56}
57
58
59
60#if HAVE_UNICODE_WCHAR1
61
62static void
63verifyNoNullsW(xmlrpc_env * const envP,
64 const wchar_t * const contents,
65 unsigned int const len) {
66/*----------------------------------------------------------------------------
67 Same as verifyNoNulls(), but for wide characters.
68-----------------------------------------------------------------------------*/
69 unsigned int i;
70
71 for (i = 0; i < len && !envP->fault_occurred; i++)
72 if (contents[i] == '\0')
73 xmlrpc_env_set_fault_formatted(
74 envP, XMLRPC_TYPE_ERROR(-501),
75 "String must not contain NUL characters");
76}
77#endif
78
79
80
81static void
82validateStringType(xmlrpc_env * const envP,
83 const xmlrpc_value * const valueP) {
84
85 if (valueP->_type != XMLRPC_TYPE_STRING) {
86 xmlrpc_env_set_fault_formatted(
87 envP, XMLRPC_TYPE_ERROR(-501), "Value of type %s supplied where "
88 "string type was expected.",
89 xmlrpc_type_name(valueP->_type));
90 }
91}
92
93
94
95static void
96accessStringValue(xmlrpc_env * const envP,
97 const xmlrpc_value * const valueP,
98 size_t * const lengthP,
99 const char ** const contentsP) {
100
101 validateStringType(envP, valueP);
102 if (!envP->fault_occurred) {
103 size_t const size =
104 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
;
105 const char * const contents =
106 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
107 size_t const len = size - 1;
108 /* The memblock has a null character added to the end */
109
110 verifyNoNulls(envP, contents, len);
111
112 *lengthP = len;
113 *contentsP = contents;
114 }
115}
116
117
118
119void
120xmlrpc_read_string(xmlrpc_env * const envP,
121 const xmlrpc_value * const valueP,
122 const char ** const stringValueP) {
123/*----------------------------------------------------------------------------
124 Read the value of an XML-RPC string as an ASCIIZ string, with
125 LF for line delimiters.
126
127 Return the string in newly malloc'ed storage that Caller must free.
128
129 Fail if the string contains null characters (which means it wasn't
130 really a string, but XML-RPC doesn't seem to understand what a string
131 is, and such values are possible).
132-----------------------------------------------------------------------------*/
133 size_t length;
134 const char * contents;
135
136 accessStringValue(envP, valueP, &length, &contents);
137
138 if (!envP->fault_occurred) {
139 char * stringValue;
140
141 MALLOCARRAY(stringValue, length + 1)do { void * array; mallocProduct(&array, length + 1, sizeof
(stringValue[0])); stringValue = array; } while (0)
;
142 if (stringValue == NULL((void*)0))
143 xmlrpc_faultf(envP, "Unable to allocate space "
144 "for %u-character string", (unsigned)length);
145 else {
146 memcpy(stringValue, contents, length);
147 stringValue[length] = '\0';
148
149 *stringValueP = stringValue;
150 }
151 }
152}
153
154
155
156static unsigned int
157lineDelimCount(const char * const start,
158 const char * const end) {
159
160 unsigned int count;
161 const char * p;
162
163 for (p = start, count = 0; p < end; ) {
164 const char * const nlPos = memchr(p, '\n', end-p);
165 if (nlPos) {
166 ++count;
167 p = nlPos + 1;
168 } else
169 p = end;
170 }
171
172 return count;
173}
174
175
176
177static void
178copyAndConvertLfToCrlf(xmlrpc_env * const envP,
179 size_t const srcLen,
180 const char * const src,
181 size_t * const dstLenP,
182 const char ** const dstP) {
183
184 const char * const srcEnd = src + srcLen;
185 unsigned int const nLineDelim = lineDelimCount(src, srcEnd);
186 size_t const dstLen = srcLen + nLineDelim;
187 char * dst;
188
189 MALLOCARRAY(dst, dstLen + 1)do { void * array; mallocProduct(&array, dstLen + 1, sizeof
(dst[0])); dst = array; } while (0)
;
190 if (dst == NULL((void*)0))
191 xmlrpc_faultf(envP, "Unable to allocate space "
192 "for %u-character string", (unsigned)dstLen + 1);
193 else {
194 const char * p; /* source pointer */
195 char * q; /* destination pointer */
196
197 for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) {
198 if (*p == '\n')
199 *q++ = '\r';
200
201 *q++ = *p;
202 }
203 XMLRPC_ASSERT(q == dst + dstLen)do if (!(q == dst + dstLen)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_string.c"
, 203); while (0)
;
204
205 *q = '\0';
206
207 *dstP = dst;
208 *dstLenP = dstLen;
209 }
210}
211
212
213
214void
215xmlrpc_read_string_crlf(xmlrpc_env * const envP,
216 const xmlrpc_value * const valueP,
217 const char ** const stringValueP) {
218/*----------------------------------------------------------------------------
219 Same as xmlrpc_read_string(), but return CRLF instead of LF for
220 line delimiters.
221-----------------------------------------------------------------------------*/
222 size_t length;
223 const char * contents;
224
225 accessStringValue(envP, valueP, &length, &contents);
226
227 if (!envP->fault_occurred) {
228 size_t stringLen;
229
230 copyAndConvertLfToCrlf(envP, length, contents,
231 &stringLen, stringValueP);
232 }
233}
234
235
236
237void
238xmlrpc_read_string_old(xmlrpc_env * const envP,
239 const xmlrpc_value * const valueP,
240 const char ** const stringValueP) {
241
242 size_t length;
243 accessStringValue(envP, valueP, &length, stringValueP);
244}
245
246
247
248void
249xmlrpc_read_string_lp(xmlrpc_env * const envP,
250 const xmlrpc_value * const valueP,
251 size_t * const lengthP,
252 const char ** const stringValueP) {
253
254 validateStringType(envP, valueP);
255 if (!envP->fault_occurred) {
256 size_t const size =
257 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
;
258 const char * const contents =
259 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
260
261 char * stringValue;
262
263 stringValue = malloc(size);
264 if (stringValue == NULL((void*)0))
265 xmlrpc_faultf(envP, "Unable to allocate %u bytes for string.",
266 (unsigned int)size);
267 else {
268 memcpy(stringValue, contents, size);
269 *stringValueP = stringValue;
270 *lengthP = size - 1; /* Size includes terminating NUL */
271 }
272 }
273}
274
275
276
277void
278xmlrpc_read_string_lp_crlf(xmlrpc_env * const envP,
279 const xmlrpc_value * const valueP,
280 size_t * const lengthP,
281 const char ** const stringValueP) {
282
283 validateStringType(envP, valueP);
284 if (!envP->fault_occurred) {
285 size_t const size =
286 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
; /* Includes NUL */
287 const char * const contents =
288 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
289
290 copyAndConvertLfToCrlf(envP, size-1, contents,
291 lengthP, stringValueP);
292 }
293}
294
295
296
297void
298xmlrpc_read_string_lp_old(xmlrpc_env * const envP,
299 const xmlrpc_value * const valueP,
300 size_t * const lengthP,
301 const char ** const stringValueP) {
302
303 validateStringType(envP, valueP);
304 if (!envP->fault_occurred) {
305 *lengthP = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
- 1;
306 *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
307 }
308}
309
310
311
312static __inline__ void
313setupWcsBlock(xmlrpc_env * const envP,
314 xmlrpc_value * const valueP) {
315/*----------------------------------------------------------------------------
316 Add a wcs block (wchar_t string) to the indicated xmlrpc_value if it
317 doesn't have one already.
318-----------------------------------------------------------------------------*/
319 if (!valueP->_wcs_block) {
320 char * const contents =
321 XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block)((char*) xmlrpc_mem_block_contents(&valueP->_block));
322 size_t const len =
323 XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block)(xmlrpc_mem_block_size(&valueP->_block) / sizeof(char)
)
- 1;
324 valueP->_wcs_block =
325 xmlrpc_utf8_to_wcs(envP, contents, len + 1);
326 }
327}
328
329
330
331#if HAVE_UNICODE_WCHAR1
332
333static void
334accessStringValueW(xmlrpc_env * const envP,
335 xmlrpc_value * const valueP,
336 size_t * const lengthP,
337 const wchar_t ** const stringValueP) {
338
339 validateStringType(envP, valueP);
340 if (!envP->fault_occurred) {
341 setupWcsBlock(envP, valueP);
342
343 if (!envP->fault_occurred) {
344 wchar_t * const wcontents =
345 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block)((wchar_t*) xmlrpc_mem_block_contents(valueP->_wcs_block));
346 size_t const len =
347 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block)(xmlrpc_mem_block_size(valueP->_wcs_block) / sizeof(wchar_t
))
- 1;
348
349 verifyNoNullsW(envP, wcontents, len);
350
351 *lengthP = len;
352 *stringValueP = wcontents;
353 }
354 }
355}
356
357
358
359void
360xmlrpc_read_string_w(xmlrpc_env * const envP,
361 xmlrpc_value * const valueP,
362 const wchar_t ** const stringValueP) {
363
364 size_t length;
365 const wchar_t * wcontents;
366
367 accessStringValueW(envP, valueP, &length, &wcontents);
368
369 if (!envP->fault_occurred) {
370 wchar_t * stringValue;
371 MALLOCARRAY(stringValue, length + 1)do { void * array; mallocProduct(&array, length + 1, sizeof
(stringValue[0])); stringValue = array; } while (0)
;
372 if (stringValue == NULL((void*)0))
373 xmlrpc_faultf(envP, "Unable to allocate space for %u-byte string",
374 (unsigned)length);
375 else {
376 memcpy(stringValue, wcontents, length * sizeof(wchar_t));
377 stringValue[length] = '\0';
378
379 *stringValueP = stringValue;
380 }
381 }
382}
383
384
385
386static unsigned int
387lineDelimCountW(const wchar_t * const start,
388 const wchar_t * const end) {
389
390 unsigned int count;
391 const wchar_t * p;
392
393 count = 0;
394 p = start;
395
396 while (p && p < end) {
397 /* We used to use memchr(), but Windows doesn't have it */
398 p = wcsstr(p, L"\n");
399 if (p && p < end) {
400 ++count; /* count the newline */
401 ++p; /* skip the newline */
402 }
403 }
404
405 return count;
406}
407
408
409
410static void
411wCopyAndConvertLfToCrlf(xmlrpc_env * const envP,
412 size_t const srcLen,
413 const wchar_t * const src,
414 size_t * const dstLenP,
415 const wchar_t ** const dstP) {
416
417 const wchar_t * const srcEnd = src + srcLen;
418 unsigned int const nLineDelim = lineDelimCountW(src, srcEnd);
419 size_t const dstLen = srcLen + nLineDelim;
420 wchar_t * dst;
421
422 MALLOCARRAY(dst, dstLen + 1)do { void * array; mallocProduct(&array, dstLen + 1, sizeof
(dst[0])); dst = array; } while (0)
;
423 if (dst == NULL((void*)0))
424 xmlrpc_faultf(envP, "Unable to allocate space "
425 "for %u-character string", (unsigned)dstLen + 1);
426 else {
427 const wchar_t * p; /* source pointer */
428 wchar_t * q; /* destination pointer */
429
430 for (p = &src[0], q = &dst[0]; p < srcEnd; ++p) {
431 if (*p == '\n')
432 *q++ = '\r';
433
434 *q++ = *p;
435 }
436 XMLRPC_ASSERT(q == dst + dstLen)do if (!(q == dst + dstLen)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_string.c"
, 436); while (0)
;
437
438 *q = '\0';
439
440 *dstP = dst;
441 *dstLenP = dstLen;
442 }
443}
444
445
446
447void
448xmlrpc_read_string_w_crlf(xmlrpc_env * const envP,
449 xmlrpc_value * const valueP,
450 const wchar_t ** const stringValueP) {
451
452 size_t size;
453 const wchar_t * contents;
454
455 accessStringValueW(envP, valueP, &size, &contents);
456
457 if (!envP->fault_occurred) {
458 size_t stringLen;
459
460 wCopyAndConvertLfToCrlf(envP, size, contents,
461 &stringLen, stringValueP);
462 }
463}
464
465
466
467void
468xmlrpc_read_string_w_old(xmlrpc_env * const envP,
469 xmlrpc_value * const valueP,
470 const wchar_t ** const stringValueP) {
471
472 size_t length;
473
474 accessStringValueW(envP, valueP, &length, stringValueP);
475}
476
477
478
479void
480xmlrpc_read_string_w_lp(xmlrpc_env * const envP,
481 xmlrpc_value * const valueP,
482 size_t * const lengthP,
483 const wchar_t ** const stringValueP) {
484
485 validateStringType(envP, valueP);
486 if (!envP->fault_occurred) {
487 setupWcsBlock(envP, valueP);
488
489 if (!envP->fault_occurred) {
490 wchar_t * const wcontents =
491 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block)((wchar_t*) xmlrpc_mem_block_contents(valueP->_wcs_block));
492 size_t const size =
493 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block)(xmlrpc_mem_block_size(valueP->_wcs_block) / sizeof(wchar_t
))
;
494
495 wchar_t * stringValue;
496
497 MALLOCARRAY(stringValue, size)do { void * array; mallocProduct(&array, size, sizeof(stringValue
[0])); stringValue = array; } while (0)
;
498 if (stringValue == NULL((void*)0))
499 xmlrpc_faultf(envP,
500 "Unable to allocate space for %u-byte string",
501 (unsigned int)size);
502 else {
503 memcpy(stringValue, wcontents, size * sizeof(wchar_t));
504
505 *lengthP = size - 1; /* size includes terminating NUL */
506 *stringValueP = stringValue;
507 }
508 }
509 }
510}
511
512
513
514void
515xmlrpc_read_string_w_lp_crlf(xmlrpc_env * const envP,
516 xmlrpc_value * const valueP,
517 size_t * const lengthP,
518 const wchar_t ** const stringValueP) {
519
520 validateStringType(envP, valueP);
521 if (!envP->fault_occurred) {
522 setupWcsBlock(envP, valueP);
523
524 if (!envP->fault_occurred) {
525 size_t const size =
526 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block)(xmlrpc_mem_block_size(valueP->_wcs_block) / sizeof(wchar_t
))
;
527 wchar_t * const wcontents =
528 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block)((wchar_t*) xmlrpc_mem_block_contents(valueP->_wcs_block));
529
530 wCopyAndConvertLfToCrlf(envP, size-1, wcontents,
531 lengthP, stringValueP);
532 }
533 }
534}
535
536
537
538void
539xmlrpc_read_string_w_lp_old(xmlrpc_env * const envP,
540 xmlrpc_value * const valueP,
541 size_t * const lengthP,
542 const wchar_t ** const stringValueP) {
543
544 validateStringType(envP, valueP);
545 if (!envP->fault_occurred) {
546 setupWcsBlock(envP, valueP);
547
548 if (!envP->fault_occurred) {
549 wchar_t * const wcontents =
550 XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block)((wchar_t*) xmlrpc_mem_block_contents(valueP->_wcs_block));
551 size_t const size =
552 XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block)(xmlrpc_mem_block_size(valueP->_wcs_block) / sizeof(wchar_t
))
;
553
554 *lengthP = size - 1; /* size includes terminating NUL */
555 *stringValueP = wcontents;
556 }
557 }
558}
559#endif /* HAVE_UNICODE_WCHAR */
560
561
562
563static void
564copyLines(xmlrpc_env * const envP,
565 const char * const src,
566 size_t const srcLen,
567 xmlrpc_mem_block * const dstP) {
568/*----------------------------------------------------------------------------
569 Copy the string 'src', 'srcLen' characters long, into 'dst', where
570 'dst' is the internal representation of string xmlrpc_value contents,
571 and 'src' has lines separated by LF, CR, and/or CRLF.
572
573 Note that the source format differs from the destination format in
574 that in the destination format, lines are separated only by newline
575 (LF).
576
577 It is tempting to believe that if we just put the user's line
578 delimiters in the xmlrpc_value here (i.e. where user has CRLF, the
579 xmlrpc_value also has CRLF), the user's line delimiters would go
580 all the way across to the XML-RPC partner. But that won't work,
581 because the XML processor on the other side will, following Section
582 2.11 of the XML spec, normalize all line endings to LF anyhow. So
583 then you might ask, why do we bother to do all the work to convert
584 them here? Because: besides just being logically cleaner, this way
585 xmlrpc_read_string() gets the proper value -- the same one the
586 XML-RPC partner would see.
587-----------------------------------------------------------------------------*/
588 /* Destination format is sometimes smaller than source (because
589 CRLF turns into LF), but never smaller. So we allocate
590 destination space equal to source size (plus one for
591 terminating NUL), but don't necessarily use it all.
592 */
593
594 /* To convert LF, CR, and CRLF to LF, all we have to do is
595 copy everything up to a CR verbatim, then insert an LF and
596 skip the CR and any following LF, and repeat.
597 */
598
599 XMLRPC_MEMBLOCK_INIT(char, envP, dstP, srcLen + 1)xmlrpc_mem_block_init((envP), (dstP), sizeof(char) * (srcLen +
1))
;
600
601 if (!envP->fault_occurred) {
602 const char * const srcEnd = &src[srcLen];
603 char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP)((char*) xmlrpc_mem_block_contents(dstP));
604
605 const char * srcCursor;
606 char * dstCursor;
607
608 for (srcCursor = &src[0], dstCursor = &contents[0];
609 srcCursor < srcEnd;) {
610
611 char * const crPos = memchr(srcCursor, '\r', srcEnd - srcCursor);
612
613 if (crPos) {
614 size_t const copyLen = crPos - srcCursor;
615 memcpy(dstCursor, srcCursor, copyLen);
616 srcCursor += copyLen;
617 dstCursor += copyLen;
618
619 *(dstCursor++) = '\n';
620
621 XMLRPC_ASSERT(*srcCursor == '\r')do if (!(*srcCursor == '\r')) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_string.c"
, 621); while (0)
;
622 ++srcCursor; /* Move past CR */
623 if (*srcCursor == '\n')
624 ++srcCursor; /* Move past LF */
625 } else {
626 size_t const remainingLen = srcEnd - srcCursor;
627 memcpy(dstCursor, srcCursor, remainingLen);
628 srcCursor += remainingLen;
629 dstCursor += remainingLen;
630 }
631 }
632
633 *dstCursor++ = '\0';
634
635 XMLRPC_ASSERT((unsigned)(dstCursor - &contents[0]) <= srcLen + 1)do if (!((unsigned)(dstCursor - &contents[0]) <= srcLen
+ 1)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_string.c"
, 635); while (0)
;
636
637 XMLRPC_MEMBLOCK_RESIZE(char, envP, dstP, dstCursor - &contents[0])xmlrpc_mem_block_resize(envP, dstP, sizeof(char) * (dstCursor
- &contents[0]))
;
638 }
639}
640
641
642
643static void
644copySimple(xmlrpc_env * const envP,
645 const char * const src,
646 size_t const srcLen,
647 xmlrpc_mem_block * const dstP) {
648/*----------------------------------------------------------------------------
649 Copy the string 'src', 'srcLen' characters long, into 'dst', where
650 'dst' is the internal representation of string xmlrpc_value contents,
651 and 'src', conveniently enough, is in the exact same format.
652
653 To wit, 'src' has lines separated by LFs only -- no CR or CRLF.
654-----------------------------------------------------------------------------*/
655 XMLRPC_MEMBLOCK_INIT(char, envP, dstP, srcLen + 1)xmlrpc_mem_block_init((envP), (dstP), sizeof(char) * (srcLen +
1))
;
656 if (!envP->fault_occurred) {
657 char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, dstP)((char*) xmlrpc_mem_block_contents(dstP));
658
659 memcpy(contents, src, srcLen);
660 contents[srcLen] = '\0';
661 }
662}
663
664
665
666enum crTreatment { CR_IS_LINEDELIM, CR_IS_CHAR };
667
668static xmlrpc_value *
669stringNew(xmlrpc_env * const envP,
670 size_t const length,
671 const char * const value,
672 enum crTreatment const crTreatment) {
673
674 xmlrpc_value * valP;
2
'valP' declared without an initial value
675
676 xmlrpc_validate_utf8(envP, value, length);
677
678 if (!envP->fault_occurred) {
3
Taking false branch
679 xmlrpc_createXmlrpcValue(envP, &valP);
680
681 if (!envP->fault_occurred) {
682 valP->_type = XMLRPC_TYPE_STRING;
683 valP->_wcs_block = NULL((void*)0);
684
685 /* Note that copyLines() works for strings with no CRs, but
686 it's slower.
687 */
688 if (memchr(value, '\r', length) && crTreatment == CR_IS_LINEDELIM)
689 copyLines(envP, value, length, &valP->_block);
690 else
691 copySimple(envP, value, length, &valP->_block);
692
693 if (envP->fault_occurred)
694 free(valP);
695 }
696 }
697 return valP;
4
Undefined or garbage value returned to caller
698}
699
700
701
702xmlrpc_value *
703xmlrpc_string_new_lp(xmlrpc_env * const envP,
704 size_t const length,
705 const char * const value) {
706
707 return stringNew(envP, length, value, CR_IS_LINEDELIM);
708}
709
710
711
712xmlrpc_value *
713xmlrpc_string_new_lp_cr(xmlrpc_env * const envP,
714 size_t const length,
715 const char * const value) {
716
717 return stringNew(envP, length, value, CR_IS_CHAR);
718}
719
720
721
722xmlrpc_value *
723xmlrpc_string_new(xmlrpc_env * const envP,
724 const char * const value) {
725
726 return stringNew(envP, strlen(value), value, CR_IS_LINEDELIM);
727}
728
729
730
731xmlrpc_value *
732xmlrpc_string_new_cr(xmlrpc_env * const envP,
733 const char * const value) {
734
735 return stringNew(envP, strlen(value), value, CR_IS_CHAR);
1
Calling 'stringNew'
736}
737
738
739
740xmlrpc_value *
741xmlrpc_string_new_va(xmlrpc_env * const envP,
742 const char * const format,
743 va_list args) {
744
745 const char * formattedString;
746 xmlrpc_value * retvalP;
747
748 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_string.c", 748); while
(0)
;
749 XMLRPC_ASSERT(format != NULL)do if (!(format != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_string.c"
, 749); while (0)
;
750
751 xmlrpc_vasprintf(&formattedString, format, args);
752
753 if (xmlrpc_strnomem(formattedString)) {
754 xmlrpc_faultf(envP, "Out of memory building formatted string");
755 retvalP = NULL((void*)0); /* defeat compiler warning */
756 } else
757 retvalP = xmlrpc_string_new(envP, formattedString);
758
759 xmlrpc_strfree(formattedString);
760
761 return retvalP;
762}
763
764
765
766xmlrpc_value *
767xmlrpc_string_new_f(xmlrpc_env * const envP,
768 const char * const format,
769 ...) {
770
771 va_list args;
772 xmlrpc_value * retval;
773
774 va_start(args, format)__builtin_va_start(args, format);
775
776 retval = xmlrpc_string_new_va(envP, format, args);
777
778 va_end(args)__builtin_va_end(args);
779
780 return retval;
781}
782
783
784
785#if HAVE_UNICODE_WCHAR1
786
787static xmlrpc_value *
788stringWNew(xmlrpc_env * const envP,
789 size_t const length,
790 const wchar_t * const value,
791 enum crTreatment const crTreatment) {
792
793 xmlrpc_value * valP;
794 xmlrpc_mem_block * utf8P;
795
796 valP = NULL((void*)0); /* defeat compiler warning */
797
798 utf8P = xmlrpc_wcs_to_utf8(envP, value, length);
799 if (!envP->fault_occurred) {
800 char * const utf8_value = XMLRPC_MEMBLOCK_CONTENTS(char, utf8P)((char*) xmlrpc_mem_block_contents(utf8P));
801 size_t const utf8_len = XMLRPC_MEMBLOCK_SIZE(char, utf8P)(xmlrpc_mem_block_size(utf8P) / sizeof(char));
802
803 if (!envP->fault_occurred) {
804 valP = stringNew(envP, utf8_len, utf8_value, crTreatment);
805
806 XMLRPC_MEMBLOCK_FREE(char, utf8P)xmlrpc_mem_block_free(utf8P);
807 }
808 }
809 return valP;
810}
811
812
813
814xmlrpc_value *
815xmlrpc_string_w_new_lp(xmlrpc_env * const envP,
816 size_t const length,
817 const wchar_t * const value) {
818
819 return stringWNew(envP, length, value, CR_IS_LINEDELIM);
820}
821
822
823
824
825xmlrpc_value *
826xmlrpc_string_w_new_lp_cr(xmlrpc_env * const envP,
827 size_t const length,
828 const wchar_t * const value) {
829
830 return stringWNew(envP, length, value, CR_IS_CHAR);
831}
832
833
834
835
836xmlrpc_value *
837xmlrpc_string_w_new(xmlrpc_env * const envP,
838 const wchar_t * const value) {
839
840 return stringWNew(envP, wcslen(value), value, CR_IS_LINEDELIM);
841}
842
843
844
845xmlrpc_value *
846xmlrpc_string_w_new_cr(xmlrpc_env * const envP,
847 const wchar_t * const value) {
848
849 return stringWNew(envP, wcslen(value), value, CR_IS_CHAR);
850}
851
852#endif /* HAVE_UNICODE_WCHAR */