File: | src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_build.c |
Location: | line 369, column 13 |
Description: | The left operand of '!=' is a garbage value |
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 "c_util.h" | |||||
12 | #include "mallocvar.h" | |||||
13 | #include "stdargx.h" | |||||
14 | ||||||
15 | #include "xmlrpc-c/base.h" | |||||
16 | #include "xmlrpc-c/base_int.h" | |||||
17 | #include "xmlrpc-c/string_int.h" | |||||
18 | ||||||
19 | ||||||
20 | ||||||
21 | static void | |||||
22 | getString(xmlrpc_env * const envP, | |||||
23 | const char ** const formatP, | |||||
24 | va_listx * const argsP, | |||||
25 | xmlrpc_value ** const valPP) { | |||||
26 | ||||||
27 | const char * str; | |||||
28 | size_t len; | |||||
29 | ||||||
30 | str = (const char*) va_arg(argsP->v, char*)__builtin_va_arg(argsP->v, char*); | |||||
31 | if (*(*formatP) == '#') { | |||||
32 | ++(*formatP); | |||||
33 | len = (size_t) va_arg(argsP->v, size_t)__builtin_va_arg(argsP->v, size_t); | |||||
34 | } else | |||||
35 | len = strlen(str); | |||||
36 | ||||||
37 | *valPP = xmlrpc_string_new_lp(envP, len, str); | |||||
38 | } | |||||
39 | ||||||
40 | ||||||
41 | ||||||
42 | static void | |||||
43 | getWideString(xmlrpc_env * const envP ATTR_UNUSED__attribute__((__unused__)), | |||||
44 | const char ** const formatP ATTR_UNUSED__attribute__((__unused__)), | |||||
45 | va_listx * const argsP ATTR_UNUSED__attribute__((__unused__)), | |||||
46 | xmlrpc_value ** const valPP ATTR_UNUSED__attribute__((__unused__))) { | |||||
47 | ||||||
48 | #if HAVE_UNICODE_WCHAR1 | |||||
49 | wchar_t *wcs; | |||||
50 | size_t len; | |||||
51 | ||||||
52 | wcs = (wchar_t*) va_arg(argsP->v, wchar_t*)__builtin_va_arg(argsP->v, wchar_t*); | |||||
53 | if (**formatP == '#') { | |||||
54 | (*formatP)++; | |||||
55 | len = (size_t) va_arg(argsP->v, size_t)__builtin_va_arg(argsP->v, size_t); | |||||
56 | } else | |||||
57 | len = wcslen(wcs); | |||||
58 | ||||||
59 | *valPP = xmlrpc_string_w_new_lp(envP, len, wcs); | |||||
60 | ||||||
61 | #endif /* HAVE_UNICODE_WCHAR */ | |||||
62 | } | |||||
63 | ||||||
64 | ||||||
65 | ||||||
66 | static void | |||||
67 | getBase64(xmlrpc_env * const envP, | |||||
68 | va_listx * const argsP, | |||||
69 | xmlrpc_value ** const valPP) { | |||||
70 | ||||||
71 | unsigned char * value; | |||||
72 | size_t length; | |||||
73 | ||||||
74 | value = (unsigned char*) va_arg(argsP->v, unsigned char*)__builtin_va_arg(argsP->v, unsigned char*); | |||||
75 | length = (size_t) va_arg(argsP->v, size_t)__builtin_va_arg(argsP->v, size_t); | |||||
76 | ||||||
77 | *valPP = xmlrpc_base64_new(envP, length, value); | |||||
78 | } | |||||
79 | ||||||
80 | ||||||
81 | ||||||
82 | static void | |||||
83 | getValue(xmlrpc_env * const envP, | |||||
84 | const char** const format, | |||||
85 | va_listx * const argsP, | |||||
86 | xmlrpc_value ** const valPP); | |||||
87 | ||||||
88 | ||||||
89 | ||||||
90 | static void | |||||
91 | getArray(xmlrpc_env * const envP, | |||||
92 | const char ** const formatP, | |||||
93 | char const delimiter, | |||||
94 | va_listx * const argsP, | |||||
95 | xmlrpc_value ** const arrayPP) { | |||||
96 | ||||||
97 | xmlrpc_value * arrayP; | |||||
98 | ||||||
99 | arrayP = xmlrpc_array_new(envP); | |||||
100 | ||||||
101 | /* Add items to the array until we hit our delimiter. */ | |||||
102 | ||||||
103 | while (**formatP != delimiter && !envP->fault_occurred) { | |||||
104 | ||||||
105 | xmlrpc_value * itemP; | |||||
106 | ||||||
107 | if (**formatP == '\0') | |||||
108 | xmlrpc_env_set_fault( | |||||
109 | envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
110 | "format string ended before closing ')'."); | |||||
111 | else { | |||||
112 | getValue(envP, formatP, argsP, &itemP); | |||||
113 | if (!envP->fault_occurred) { | |||||
114 | xmlrpc_array_append_item(envP, arrayP, itemP); | |||||
115 | xmlrpc_DECREF(itemP); | |||||
116 | } | |||||
117 | } | |||||
118 | } | |||||
119 | if (envP->fault_occurred) | |||||
120 | xmlrpc_DECREF(arrayP); | |||||
121 | ||||||
122 | *arrayPP = arrayP; | |||||
123 | } | |||||
124 | ||||||
125 | ||||||
126 | ||||||
127 | static void | |||||
128 | getStructMember(xmlrpc_env * const envP, | |||||
129 | const char ** const formatP, | |||||
130 | va_listx * const argsP, | |||||
131 | xmlrpc_value ** const keyPP, | |||||
132 | xmlrpc_value ** const valuePP) { | |||||
133 | ||||||
134 | ||||||
135 | /* Get the key */ | |||||
136 | getValue(envP, formatP, argsP, keyPP); | |||||
137 | if (!envP->fault_occurred) { | |||||
138 | if (**formatP != ':') | |||||
139 | xmlrpc_env_set_fault( | |||||
140 | envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
141 | "format string does not have ':' after a " | |||||
142 | "structure member key."); | |||||
143 | else { | |||||
144 | /* Skip over colon that separates key from value */ | |||||
145 | (*formatP)++; | |||||
146 | ||||||
147 | /* Get the value */ | |||||
148 | getValue(envP, formatP, argsP, valuePP); | |||||
149 | } | |||||
150 | if (envP->fault_occurred) | |||||
151 | xmlrpc_DECREF(*keyPP); | |||||
152 | } | |||||
153 | } | |||||
154 | ||||||
155 | ||||||
156 | ||||||
157 | static void | |||||
158 | getStruct(xmlrpc_env * const envP, | |||||
159 | const char ** const formatP, | |||||
160 | char const delimiter, | |||||
161 | va_listx * const argsP, | |||||
162 | xmlrpc_value ** const structPP) { | |||||
163 | ||||||
164 | xmlrpc_value * structP; | |||||
165 | ||||||
166 | structP = xmlrpc_struct_new(envP); | |||||
167 | if (!envP->fault_occurred) { | |||||
168 | while (**formatP != delimiter && !envP->fault_occurred) { | |||||
169 | xmlrpc_value * keyP; | |||||
170 | xmlrpc_value * valueP; | |||||
171 | ||||||
172 | getStructMember(envP, formatP, argsP, &keyP, &valueP); | |||||
173 | ||||||
174 | if (!envP->fault_occurred) { | |||||
175 | if (**formatP == ',') | |||||
176 | (*formatP)++; /* Skip over the comma */ | |||||
177 | else if (**formatP == delimiter) { | |||||
178 | /* End of the line */ | |||||
179 | } else | |||||
180 | xmlrpc_env_set_fault( | |||||
181 | envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
182 | "format string does not have ',' or ')' after " | |||||
183 | "a structure member"); | |||||
184 | ||||||
185 | if (!envP->fault_occurred) | |||||
186 | /* Add the new member to the struct. */ | |||||
187 | xmlrpc_struct_set_value_v(envP, structP, keyP, valueP); | |||||
188 | ||||||
189 | xmlrpc_DECREF(valueP); | |||||
190 | xmlrpc_DECREF(keyP); | |||||
191 | } | |||||
192 | } | |||||
193 | if (envP->fault_occurred) | |||||
194 | xmlrpc_DECREF(structP); | |||||
195 | } | |||||
196 | *structPP = structP; | |||||
197 | } | |||||
198 | ||||||
199 | ||||||
200 | ||||||
201 | static void | |||||
202 | mkArrayFromVal(xmlrpc_env * const envP, | |||||
203 | xmlrpc_value * const value, | |||||
204 | xmlrpc_value ** const valPP) { | |||||
205 | ||||||
206 | if (xmlrpc_value_type(value) != XMLRPC_TYPE_ARRAY) | |||||
207 | xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
208 | "Array format ('A'), non-array xmlrpc_value"); | |||||
209 | else | |||||
210 | xmlrpc_INCREF(value); | |||||
211 | ||||||
212 | *valPP = value; | |||||
213 | } | |||||
214 | ||||||
215 | ||||||
216 | ||||||
217 | static void | |||||
218 | mkStructFromVal(xmlrpc_env * const envP, | |||||
219 | xmlrpc_value * const value, | |||||
220 | xmlrpc_value ** const valPP) { | |||||
221 | ||||||
222 | if (xmlrpc_value_type(value) != XMLRPC_TYPE_STRUCT) | |||||
223 | xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
224 | "Struct format ('S'), non-struct xmlrpc_value"); | |||||
225 | else | |||||
226 | xmlrpc_INCREF(value); | |||||
227 | ||||||
228 | *valPP = value; | |||||
229 | } | |||||
230 | ||||||
231 | ||||||
232 | ||||||
233 | static void | |||||
234 | getValue(xmlrpc_env * const envP, | |||||
235 | const char** const formatP, | |||||
236 | va_listx * const argsP, | |||||
237 | xmlrpc_value ** const valPP) { | |||||
238 | /*---------------------------------------------------------------------------- | |||||
239 | Get the next value from the list. *formatP points to the specifier | |||||
240 | for the next value in the format string (i.e. to the type code | |||||
241 | character) and we move *formatP past the whole specifier for the | |||||
242 | next value. We read the required arguments from 'argsP'. We return | |||||
243 | the value as *valPP with a reference to it. | |||||
244 | ||||||
245 | For example, if *formatP points to the "i" in the string "sis", | |||||
246 | we read one argument from 'argsP' and return as *valP an integer whose | |||||
247 | value is the argument we read. We advance *formatP to point to the | |||||
248 | last 's' and advance 'argsP' to point to the argument that belongs to | |||||
249 | that 's'. | |||||
250 | -----------------------------------------------------------------------------*/ | |||||
251 | char const formatChar = *(*formatP)++; | |||||
252 | ||||||
253 | switch (formatChar) { | |||||
254 | case 'i': | |||||
255 | *valPP = | |||||
256 | xmlrpc_int_new(envP, (xmlrpc_int32) va_arg(argsP->v,__builtin_va_arg(argsP->v, xmlrpc_int32) | |||||
257 | xmlrpc_int32)__builtin_va_arg(argsP->v, xmlrpc_int32)); | |||||
258 | break; | |||||
259 | ||||||
260 | case 'b': | |||||
261 | *valPP = | |||||
262 | xmlrpc_bool_new(envP, (xmlrpc_bool) va_arg(argsP->v, xmlrpc_bool)__builtin_va_arg(argsP->v, xmlrpc_bool)); | |||||
263 | break; | |||||
264 | ||||||
265 | case 'd': | |||||
266 | *valPP = | |||||
267 | xmlrpc_double_new(envP, (double) va_arg(argsP->v, double)__builtin_va_arg(argsP->v, double)); | |||||
268 | break; | |||||
269 | ||||||
270 | case 's': | |||||
271 | getString(envP, formatP, argsP, valPP); | |||||
272 | break; | |||||
273 | ||||||
274 | case 'w': | |||||
275 | getWideString(envP, formatP, argsP, valPP); | |||||
276 | break; | |||||
277 | ||||||
278 | case 't': | |||||
279 | *valPP = xmlrpc_datetime_new_sec(envP, va_arg(argsP->v, time_t)__builtin_va_arg(argsP->v, time_t)); | |||||
280 | break; | |||||
281 | ||||||
282 | case '8': | |||||
283 | *valPP = xmlrpc_datetime_new_str(envP, va_arg(argsP->v, char*)__builtin_va_arg(argsP->v, char*)); | |||||
284 | break; | |||||
285 | ||||||
286 | case '6': | |||||
287 | getBase64(envP, argsP, valPP); | |||||
288 | break; | |||||
289 | ||||||
290 | case 'n': | |||||
291 | *valPP = | |||||
292 | xmlrpc_nil_new(envP); | |||||
293 | break; | |||||
294 | ||||||
295 | case 'I': | |||||
296 | *valPP = | |||||
297 | xmlrpc_i8_new(envP, (xmlrpc_int64) va_arg(argsP->v, xmlrpc_int64)__builtin_va_arg(argsP->v, xmlrpc_int64)); | |||||
298 | break; | |||||
299 | ||||||
300 | case 'p': | |||||
301 | *valPP = | |||||
302 | xmlrpc_cptr_new(envP, (void*) va_arg(argsP->v, void*)__builtin_va_arg(argsP->v, void*)); | |||||
303 | break; | |||||
304 | ||||||
305 | case 'A': | |||||
306 | mkArrayFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*)__builtin_va_arg(argsP->v, xmlrpc_value*), | |||||
307 | valPP); | |||||
308 | break; | |||||
309 | ||||||
310 | case 'S': | |||||
311 | mkStructFromVal(envP, (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*)__builtin_va_arg(argsP->v, xmlrpc_value*), | |||||
312 | valPP); | |||||
313 | break; | |||||
314 | ||||||
315 | case 'V': | |||||
316 | *valPP = (xmlrpc_value*) va_arg(argsP->v, xmlrpc_value*)__builtin_va_arg(argsP->v, xmlrpc_value*); | |||||
317 | xmlrpc_INCREF(*valPP); | |||||
318 | break; | |||||
319 | ||||||
320 | case '(': | |||||
321 | getArray(envP, formatP, ')', argsP, valPP); | |||||
322 | if (!envP->fault_occurred) { | |||||
323 | XMLRPC_ASSERT(**formatP == ')')do if (!(**formatP == ')')) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_build.c" , 323); while (0); | |||||
324 | (*formatP)++; /* Skip over closing parenthesis */ | |||||
325 | } | |||||
326 | break; | |||||
327 | ||||||
328 | case '{': | |||||
329 | getStruct(envP, formatP, '}', argsP, valPP); | |||||
330 | if (!envP->fault_occurred) { | |||||
331 | XMLRPC_ASSERT(**formatP == '}')do if (!(**formatP == '}')) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_build.c" , 331); while (0); | |||||
332 | (*formatP)++; /* Skip over closing brace */ | |||||
333 | } | |||||
334 | break; | |||||
335 | ||||||
336 | default: { | |||||
337 | const char * const badCharacter = xmlrpc_makePrintableChar(formatChar); | |||||
338 | xmlrpc_env_set_fault_formatted( | |||||
339 | envP, XMLRPC_INTERNAL_ERROR(-500), | |||||
340 | "Unexpected character '%s' in format string", badCharacter); | |||||
341 | xmlrpc_strfree(badCharacter); | |||||
342 | } | |||||
343 | } | |||||
344 | } | |||||
345 | ||||||
346 | ||||||
347 | ||||||
348 | void | |||||
349 | xmlrpc_build_value_va(xmlrpc_env * const envP, | |||||
350 | const char * const format, | |||||
351 | va_list const args, | |||||
352 | xmlrpc_value ** const valPP, | |||||
353 | const char ** const tailP) { | |||||
354 | ||||||
355 | 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_build.c", 355); while ( 0); | |||||
356 | XMLRPC_ASSERT(format != NULL)do if (!(format != ((void*)0))) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_build.c" , 356); while (0); | |||||
357 | ||||||
358 | if (strlen(format) == 0) | |||||
359 | xmlrpc_faultf(envP, "Format string is empty."); | |||||
360 | else { | |||||
361 | va_listx currentArgs; | |||||
362 | const char * formatCursor; | |||||
363 | ||||||
364 | init_va_listx(¤tArgs, args); | |||||
365 | formatCursor = &format[0]; | |||||
366 | getValue(envP, &formatCursor, ¤tArgs, valPP); | |||||
367 | ||||||
368 | if (!envP->fault_occurred) | |||||
369 | XMLRPC_ASSERT_VALUE_OK(*valPP)do if (!((*valPP) != ((void*)0) && (*valPP)->_type != XMLRPC_TYPE_DEAD)) xmlrpc_assertion_failed("../../../../libs/xmlrpc-c/src/xmlrpc_build.c" , 369); while (0); | |||||
| ||||||
370 | ||||||
371 | *tailP = formatCursor; | |||||
372 | } | |||||
373 | } | |||||
374 | ||||||
375 | ||||||
376 | ||||||
377 | xmlrpc_value * | |||||
378 | xmlrpc_build_value(xmlrpc_env * const envP, | |||||
379 | const char * const format, | |||||
380 | ...) { | |||||
381 | ||||||
382 | va_list args; | |||||
383 | xmlrpc_value * retval; | |||||
384 | const char * suffix; | |||||
385 | ||||||
386 | va_start(args, format)__builtin_va_start(args, format); | |||||
387 | xmlrpc_build_value_va(envP, format, args, &retval, &suffix); | |||||
| ||||||
388 | va_end(args)__builtin_va_end(args); | |||||
389 | ||||||
390 | if (!envP->fault_occurred) { | |||||
391 | if (*suffix != '\0') | |||||
392 | xmlrpc_faultf(envP, "Junk after the format specifier: '%s'. " | |||||
393 | "The format string must describe exactly " | |||||
394 | "one XML-RPC value " | |||||
395 | "(but it might be a compound value " | |||||
396 | "such as an array)", | |||||
397 | suffix); | |||||
398 | ||||||
399 | if (envP->fault_occurred) | |||||
400 | xmlrpc_DECREF(retval); | |||||
401 | } | |||||
402 | return retval; | |||||
403 | } | |||||
404 | ||||||
405 | ||||||
406 | /* Copyright (C) 2001 by First Peer, Inc. All rights reserved. | |||||
407 | ** Copyright (C) 2001 by Eric Kidd. All rights reserved. | |||||
408 | ** | |||||
409 | ** Redistribution and use in source and binary forms, with or without | |||||
410 | ** modification, are permitted provided that the following conditions | |||||
411 | ** are met: | |||||
412 | ** 1. Redistributions of source code must retain the above copyright | |||||
413 | ** notice, this list of conditions and the following disclaimer. | |||||
414 | ** 2. Redistributions in binary form must reproduce the above copyright | |||||
415 | ** notice, this list of conditions and the following disclaimer in the | |||||
416 | ** documentation and/or other materials provided with the distribution. | |||||
417 | ** 3. The name of the author may not be used to endorse or promote products | |||||
418 | ** derived from this software without specific prior written permission. | |||||
419 | ** | |||||
420 | ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
421 | ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
422 | ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
423 | ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
424 | ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
425 | ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
426 | ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
427 | ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
428 | ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
429 | ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
430 | ** SUCH DAMAGE. */ |