| File: | src/mod/xml_int/mod_xml_rpc/../../../../libs/xmlrpc-c/src/xmlrpc_build.c |
| Location: | line 189, column 17 |
| Description: | Function call argument is an uninitialized 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. */ |