xmlrpc_data.c 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331
  1. /* Copyright information is at end of file */
  2. #include "xmlrpc_config.h"
  3. #include <stddef.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include "bool.h"
  8. #include "xmlrpc.h"
  9. #include "xmlrpc_int.h"
  10. /* Borrowed from Python 1.5.2.
  11. ** MPW pushes 'extended' for float and double types with varargs */
  12. #ifdef MPW
  13. typedef extended va_double;
  14. #else
  15. typedef double va_double;
  16. #endif
  17. /* Borrowed from Python 1.5.2.
  18. ** Python copies its va_list objects before using them in certain
  19. ** tricky fashions. We don't why Python does this, but since we're
  20. ** abusing our va_list objects in a similar fashion, we'll copy them
  21. ** too. */
  22. #if VA_LIST_IS_ARRAY
  23. #define VA_LIST_COPY(dest,src) memcpy((dest), (src), sizeof(va_list))
  24. #else
  25. #define VA_LIST_COPY(dest,src) ((dest) = (src))
  26. #endif
  27. static void
  28. destroyValue(xmlrpc_value * const valueP) {
  29. /* First, we need to destroy this value's contents, if any. */
  30. switch (valueP->_type) {
  31. case XMLRPC_TYPE_INT:
  32. case XMLRPC_TYPE_BOOL:
  33. case XMLRPC_TYPE_DOUBLE:
  34. break;
  35. case XMLRPC_TYPE_ARRAY:
  36. xmlrpc_destroyArrayContents(valueP);
  37. break;
  38. case XMLRPC_TYPE_STRING:
  39. #ifdef HAVE_UNICODE_WCHAR
  40. if (valueP->_wcs_block)
  41. xmlrpc_mem_block_free(valueP->_wcs_block);
  42. #endif /* HAVE_UNICODE_WCHAR */
  43. /* Fall through. */
  44. case XMLRPC_TYPE_DATETIME:
  45. case XMLRPC_TYPE_BASE64:
  46. xmlrpc_mem_block_clean(&valueP->_block);
  47. break;
  48. case XMLRPC_TYPE_STRUCT:
  49. xmlrpc_destroyStruct(valueP);
  50. break;
  51. case XMLRPC_TYPE_C_PTR:
  52. break;
  53. case XMLRPC_TYPE_DEAD:
  54. XMLRPC_ASSERT(FALSE); /* Can't happen, per entry conditions */
  55. default:
  56. XMLRPC_ASSERT(FALSE); /* There are no other possible values */
  57. }
  58. /* Next, we mark this value as invalid, to help catch refcount
  59. ** errors. */
  60. valueP->_type = XMLRPC_TYPE_DEAD;
  61. /* Finally, we destroy the value itself. */
  62. free(valueP);
  63. }
  64. /*=========================================================================
  65. ** Reference Counting
  66. **=========================================================================
  67. ** Some simple reference-counting code. The xmlrpc_DECREF routine is in
  68. ** charge of destroying values when their reference count equals zero.
  69. */
  70. void
  71. xmlrpc_INCREF (xmlrpc_value * const valueP) {
  72. XMLRPC_ASSERT_VALUE_OK(valueP);
  73. XMLRPC_ASSERT(valueP->_refcount > 0);
  74. valueP->_refcount++;
  75. }
  76. void
  77. xmlrpc_DECREF (xmlrpc_value * const valueP) {
  78. XMLRPC_ASSERT_VALUE_OK(valueP);
  79. XMLRPC_ASSERT(valueP->_refcount > 0);
  80. XMLRPC_ASSERT(valueP->_type != XMLRPC_TYPE_DEAD);
  81. valueP->_refcount--;
  82. /* If we have no more refs, we need to deallocate this value. */
  83. if (valueP->_refcount == 0)
  84. destroyValue(valueP);
  85. }
  86. /*=========================================================================
  87. Utiltiies
  88. =========================================================================*/
  89. static const char *
  90. typeName(xmlrpc_type const type) {
  91. switch(type) {
  92. case XMLRPC_TYPE_INT: return "INT";
  93. case XMLRPC_TYPE_BOOL: return "BOOL";
  94. case XMLRPC_TYPE_DOUBLE: return "DOUBLE";
  95. case XMLRPC_TYPE_DATETIME: return "DATETIME";
  96. case XMLRPC_TYPE_STRING: return "STRING";
  97. case XMLRPC_TYPE_BASE64: return "BASE64";
  98. case XMLRPC_TYPE_ARRAY: return "ARRAY";
  99. case XMLRPC_TYPE_STRUCT: return "STRUCT";
  100. case XMLRPC_TYPE_C_PTR: return "C_PTR";
  101. case XMLRPC_TYPE_DEAD: return "DEAD";
  102. default: return "???";
  103. }
  104. }
  105. static void
  106. verifyNoNulls(xmlrpc_env * const envP,
  107. const char * const contents,
  108. unsigned int const len) {
  109. /*----------------------------------------------------------------------------
  110. Verify that the character array 'contents', which is 'len' bytes long,
  111. does not contain any NUL characters, which means it can be made into
  112. a passable ASCIIZ string just by adding a terminating NUL.
  113. Fail if the array contains a NUL.
  114. -----------------------------------------------------------------------------*/
  115. unsigned int i;
  116. for (i = 0; i < len && !envP->fault_occurred; i++)
  117. if (contents[i] == '\0')
  118. xmlrpc_env_set_fault_formatted(
  119. envP, XMLRPC_TYPE_ERROR,
  120. "String must not contain NUL characters");
  121. }
  122. static void
  123. verifyNoNullsW(xmlrpc_env * const envP,
  124. const wchar_t * const contents,
  125. unsigned int const len) {
  126. /*----------------------------------------------------------------------------
  127. Same as verifyNoNulls(), but for wide characters.
  128. -----------------------------------------------------------------------------*/
  129. unsigned int i;
  130. for (i = 0; i < len && !envP->fault_occurred; i++)
  131. if (contents[i] == '\0')
  132. xmlrpc_env_set_fault_formatted(
  133. envP, XMLRPC_TYPE_ERROR,
  134. "String must not contain NUL characters");
  135. }
  136. static void
  137. validateType(xmlrpc_env * const envP,
  138. const xmlrpc_value * const valueP,
  139. xmlrpc_type const expectedType) {
  140. if (valueP->_type != expectedType) {
  141. xmlrpc_env_set_fault_formatted(
  142. envP, XMLRPC_TYPE_ERROR, "Value of type %s supplied where "
  143. "type %s was expected.",
  144. typeName(valueP->_type), typeName(expectedType));
  145. }
  146. }
  147. /*=========================================================================
  148. Extracting XML-RPC value
  149. ===========================================================================
  150. These routines extract XML-RPC values into ordinary C data types.
  151. For array and struct values, see the separates files xmlrpc_array.c
  152. and xmlrpc_struct.c.
  153. =========================================================================*/
  154. void
  155. xmlrpc_read_int(xmlrpc_env * const envP,
  156. const xmlrpc_value * const valueP,
  157. xmlrpc_int32 * const intValueP) {
  158. validateType(envP, valueP, XMLRPC_TYPE_INT);
  159. if (!envP->fault_occurred)
  160. *intValueP = valueP->_value.i;
  161. }
  162. void
  163. xmlrpc_read_double(xmlrpc_env * const envP,
  164. const xmlrpc_value * const valueP,
  165. xmlrpc_double * const doubleValueP) {
  166. validateType(envP, valueP, XMLRPC_TYPE_DOUBLE);
  167. if (!envP->fault_occurred)
  168. *doubleValueP = valueP->_value.d;
  169. }
  170. void
  171. xmlrpc_read_bool(xmlrpc_env * const envP,
  172. const xmlrpc_value * const valueP,
  173. xmlrpc_bool * const boolValueP) {
  174. validateType(envP, valueP, XMLRPC_TYPE_BOOL);
  175. if (!envP->fault_occurred)
  176. *boolValueP = valueP->_value.b;
  177. }
  178. void
  179. xmlrpc_read_string(xmlrpc_env * const envP,
  180. const xmlrpc_value * const valueP,
  181. const char ** const stringValueP) {
  182. /*----------------------------------------------------------------------------
  183. Read the value of an XML-RPC string an ASCIIZ string.
  184. Fail if the string contains null characters (which means it wasn't
  185. really a string, but XML-RPC doesn't seem to understand what a string
  186. is, and such values are possible).
  187. -----------------------------------------------------------------------------*/
  188. validateType(envP, valueP, XMLRPC_TYPE_STRING);
  189. if (!envP->fault_occurred) {
  190. unsigned int const size =
  191. XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
  192. const char * const contents =
  193. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
  194. verifyNoNulls(envP, contents, size);
  195. if (!envP->fault_occurred) {
  196. char * stringValue;
  197. stringValue = malloc(size+1);
  198. if (stringValue == NULL)
  199. xmlrpc_env_set_fault_formatted(
  200. envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate space "
  201. "for %u-character string", size);
  202. else {
  203. memcpy(stringValue,
  204. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block), size);
  205. stringValue[size] = '\0';
  206. *stringValueP = stringValue;
  207. }
  208. }
  209. }
  210. }
  211. void
  212. xmlrpc_read_string_lp(xmlrpc_env * const envP,
  213. const xmlrpc_value * const valueP,
  214. unsigned int * const lengthP,
  215. const char ** const stringValueP) {
  216. validateType(envP, valueP, XMLRPC_TYPE_STRING);
  217. if (!envP->fault_occurred) {
  218. unsigned int const size =
  219. XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
  220. const char * const contents =
  221. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
  222. char * stringValue;
  223. stringValue = malloc(size);
  224. if (stringValue == NULL)
  225. xmlrpc_env_set_fault_formatted(
  226. envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate %u bytes "
  227. "for string.", size);
  228. else {
  229. memcpy(stringValue, contents, size);
  230. *stringValueP = stringValue;
  231. *lengthP = size;
  232. }
  233. }
  234. }
  235. /*=========================================================================
  236. ** Building XML-RPC values.
  237. **=========================================================================
  238. ** Build new XML-RPC values from a format string. This code is heavily
  239. ** inspired by Py_BuildValue from Python 1.5.2. In particular, our
  240. ** particular abuse of the va_list data type is copied from the equivalent
  241. ** Python code in modsupport.c. Since Python is portable, our code should
  242. ** (in theory) also be portable.
  243. */
  244. xmlrpc_type xmlrpc_value_type (xmlrpc_value* value)
  245. {
  246. XMLRPC_ASSERT_VALUE_OK(value);
  247. return value->_type;
  248. }
  249. static void
  250. createXmlrpcValue(xmlrpc_env * const envP,
  251. xmlrpc_value ** const valPP) {
  252. /*----------------------------------------------------------------------------
  253. Create a blank xmlrpc_value to be filled in.
  254. Set the reference count to 1.
  255. -----------------------------------------------------------------------------*/
  256. xmlrpc_value * valP;
  257. valP = (xmlrpc_value*) malloc(sizeof(xmlrpc_value));
  258. if (!valP)
  259. xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
  260. "Could not allocate memory for xmlrpc_value");
  261. else
  262. valP->_refcount = 1;
  263. *valPP = valP;
  264. }
  265. static void
  266. mkInt(xmlrpc_env * const envP,
  267. xmlrpc_int32 const value,
  268. xmlrpc_value ** const valPP) {
  269. xmlrpc_value * valP;
  270. createXmlrpcValue(envP, &valP);
  271. if (!envP->fault_occurred) {
  272. valP->_type = XMLRPC_TYPE_INT;
  273. valP->_value.i = value;
  274. }
  275. *valPP = valP;
  276. }
  277. static void
  278. mkBool(xmlrpc_env * const envP,
  279. xmlrpc_bool const value,
  280. xmlrpc_value ** const valPP) {
  281. xmlrpc_value * valP;
  282. createXmlrpcValue(envP, &valP);
  283. if (!envP->fault_occurred) {
  284. valP->_type = XMLRPC_TYPE_BOOL;
  285. valP->_value.b = value;
  286. }
  287. *valPP = valP;
  288. }
  289. static void
  290. mkDouble(xmlrpc_env * const envP,
  291. double const value,
  292. xmlrpc_value ** const valPP) {
  293. xmlrpc_value * valP;
  294. createXmlrpcValue(envP, &valP);
  295. if (!envP->fault_occurred) {
  296. valP->_type = XMLRPC_TYPE_DOUBLE;
  297. valP->_value.d = value;
  298. }
  299. *valPP = valP;
  300. }
  301. #ifdef HAVE_UNICODE_WCHAR
  302. #define MAKE_WCS_BLOCK_NULL(val) ((val)->_wcs_block = NULL)
  303. #else
  304. #define MAKE_WCS_BLOCK_NULL(val) while (0) do {};
  305. #endif
  306. static void
  307. mkString(xmlrpc_env * const envP,
  308. const char * const value,
  309. unsigned int const length,
  310. xmlrpc_value ** const valPP) {
  311. xmlrpc_value * valP;
  312. createXmlrpcValue(envP, &valP);
  313. if (!envP->fault_occurred) {
  314. valP->_type = XMLRPC_TYPE_STRING;
  315. MAKE_WCS_BLOCK_NULL(valP);
  316. XMLRPC_MEMBLOCK_INIT(char, envP, &valP->_block, length + 1);
  317. if (!envP->fault_occurred) {
  318. char * const contents =
  319. XMLRPC_MEMBLOCK_CONTENTS(char, &valP->_block);
  320. memcpy(contents, value, length);
  321. contents[length] = '\0';
  322. }
  323. if (envP->fault_occurred)
  324. free(valP);
  325. }
  326. *valPP = valP;
  327. }
  328. static void
  329. getString(xmlrpc_env * const envP,
  330. const char ** const formatP,
  331. va_list * const args,
  332. xmlrpc_value ** const valPP) {
  333. const char * str;
  334. unsigned int len;
  335. str = (const char*) va_arg(*args, char*);
  336. if (**formatP == '#') {
  337. (*formatP)++;
  338. len = (size_t) va_arg(*args, size_t);
  339. } else
  340. len = strlen(str);
  341. mkString(envP, str, len, valPP);
  342. }
  343. #ifdef HAVE_UNICODE_WCHAR
  344. static void
  345. mkWideString(xmlrpc_env * const envP,
  346. wchar_t * const wcs,
  347. size_t const wcs_len,
  348. xmlrpc_value ** const valPP) {
  349. xmlrpc_value * valP;
  350. char *contents;
  351. wchar_t *wcs_contents;
  352. int block_is_inited;
  353. xmlrpc_mem_block *utf8_block;
  354. char *utf8_contents;
  355. size_t utf8_len;
  356. /* Error-handling preconditions. */
  357. valP = NULL;
  358. utf8_block = NULL;
  359. block_is_inited = 0;
  360. /* Initialize our XML-RPC value. */
  361. valP = (xmlrpc_value*) malloc(sizeof(xmlrpc_value));
  362. XMLRPC_FAIL_IF_NULL(valP, envP, XMLRPC_INTERNAL_ERROR,
  363. "Could not allocate memory for wide string");
  364. valP->_refcount = 1;
  365. valP->_type = XMLRPC_TYPE_STRING;
  366. /* More error-handling preconditions. */
  367. valP->_wcs_block = NULL;
  368. /* Build our wchar_t block first. */
  369. valP->_wcs_block =
  370. XMLRPC_TYPED_MEM_BLOCK_NEW(wchar_t, envP, wcs_len + 1);
  371. XMLRPC_FAIL_IF_FAULT(envP);
  372. wcs_contents =
  373. XMLRPC_TYPED_MEM_BLOCK_CONTENTS(wchar_t, valP->_wcs_block);
  374. memcpy(wcs_contents, wcs, wcs_len * sizeof(wchar_t));
  375. wcs_contents[wcs_len] = '\0';
  376. /* Convert the wcs block to UTF-8. */
  377. utf8_block = xmlrpc_wcs_to_utf8(envP, wcs_contents, wcs_len + 1);
  378. XMLRPC_FAIL_IF_FAULT(envP);
  379. utf8_contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, utf8_block);
  380. utf8_len = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, utf8_block);
  381. /* XXX - We need an extra memcopy to initialize _block. */
  382. XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &valP->_block, utf8_len);
  383. XMLRPC_FAIL_IF_FAULT(envP);
  384. block_is_inited = 1;
  385. contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &valP->_block);
  386. memcpy(contents, utf8_contents, utf8_len);
  387. cleanup:
  388. if (utf8_block)
  389. xmlrpc_mem_block_free(utf8_block);
  390. if (envP->fault_occurred) {
  391. if (valP) {
  392. if (valP->_wcs_block)
  393. xmlrpc_mem_block_free(valP->_wcs_block);
  394. if (block_is_inited)
  395. xmlrpc_mem_block_clean(&valP->_block);
  396. free(valP);
  397. }
  398. }
  399. *valPP = valP;
  400. }
  401. #endif /* HAVE_UNICODE_WCHAR */
  402. static void
  403. getWideString(xmlrpc_env * const envP,
  404. const char ** const formatP,
  405. va_list * const args,
  406. xmlrpc_value ** const valPP) {
  407. #ifdef HAVE_UNICODE_WCHAR
  408. wchar_t *wcs;
  409. size_t len;
  410. wcs = (wchar_t*) va_arg(*args, wchar_t*);
  411. if (**formatP == '#') {
  412. (*formatP)++;
  413. len = (size_t) va_arg(*args, size_t);
  414. } else
  415. len = wcslen(wcs);
  416. mkWideString(envP, wcs, len, valPP);
  417. #endif /* HAVE_UNICODE_WCHAR */
  418. }
  419. static void
  420. mkDatetime(xmlrpc_env * const envP,
  421. const char * const value,
  422. xmlrpc_value ** const valPP) {
  423. xmlrpc_value * valP;
  424. createXmlrpcValue(envP, &valP);
  425. if (!envP->fault_occurred) {
  426. valP->_type = XMLRPC_TYPE_DATETIME;
  427. XMLRPC_TYPED_MEM_BLOCK_INIT(
  428. char, envP, &valP->_block, strlen(value) + 1);
  429. if (!envP->fault_occurred) {
  430. char * const contents =
  431. XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &valP->_block);
  432. strcpy(contents, value);
  433. }
  434. if (envP->fault_occurred)
  435. free(valP);
  436. }
  437. *valPP = valP;
  438. }
  439. static void
  440. mkBase64(xmlrpc_env * const envP,
  441. const unsigned char * const value,
  442. size_t const length,
  443. xmlrpc_value ** const valPP) {
  444. xmlrpc_value * valP;
  445. createXmlrpcValue(envP, &valP);
  446. if (!envP->fault_occurred) {
  447. valP->_type = XMLRPC_TYPE_BASE64;
  448. xmlrpc_mem_block_init(envP, &valP->_block, length);
  449. if (!envP->fault_occurred) {
  450. char * const contents =
  451. xmlrpc_mem_block_contents(&valP->_block);
  452. memcpy(contents, value, length);
  453. }
  454. if (envP->fault_occurred)
  455. free(valP);
  456. }
  457. *valPP = valP;
  458. }
  459. static void
  460. getBase64(xmlrpc_env * const envP,
  461. va_list * const args,
  462. xmlrpc_value ** const valPP) {
  463. unsigned char * value;
  464. size_t length;
  465. value = (unsigned char*) va_arg(*args, unsigned char*);
  466. length = (size_t) va_arg(*args, size_t);
  467. mkBase64(envP, value, length, valPP);
  468. }
  469. static void
  470. mkCPtr(xmlrpc_env * const envP,
  471. void * const value,
  472. xmlrpc_value ** const valPP) {
  473. xmlrpc_value * valP;
  474. createXmlrpcValue(envP, &valP);
  475. if (!envP->fault_occurred) {
  476. valP->_type = XMLRPC_TYPE_C_PTR;
  477. valP->_value.c_ptr = value;
  478. }
  479. *valPP = valP;
  480. }
  481. static void
  482. mkArrayFromVal(xmlrpc_env * const envP,
  483. xmlrpc_value * const value,
  484. xmlrpc_value ** const valPP) {
  485. if (xmlrpc_value_type(value) != XMLRPC_TYPE_ARRAY)
  486. xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
  487. "Array format ('A'), non-array xmlrpc_value");
  488. else
  489. xmlrpc_INCREF(value);
  490. *valPP = value;
  491. }
  492. static void
  493. mkStructFromVal(xmlrpc_env * const envP,
  494. xmlrpc_value * const value,
  495. xmlrpc_value ** const valPP) {
  496. if (xmlrpc_value_type(value) != XMLRPC_TYPE_STRUCT)
  497. xmlrpc_env_set_fault(envP, XMLRPC_INTERNAL_ERROR,
  498. "Struct format ('S'), non-struct xmlrpc_value");
  499. else
  500. xmlrpc_INCREF(value);
  501. *valPP = value;
  502. }
  503. static void
  504. getValue(xmlrpc_env * const envP,
  505. const char** const format,
  506. va_list * const args,
  507. xmlrpc_value ** const valPP);
  508. static void
  509. createXmlrpcArray(xmlrpc_env * const envP,
  510. xmlrpc_value ** const arrayPP) {
  511. /*----------------------------------------------------------------------------
  512. Create an empty array xmlrpc_value.
  513. -----------------------------------------------------------------------------*/
  514. xmlrpc_value * arrayP;
  515. createXmlrpcValue(envP, &arrayP);
  516. if (!envP->fault_occurred) {
  517. arrayP->_type = XMLRPC_TYPE_ARRAY;
  518. XMLRPC_TYPED_MEM_BLOCK_INIT(xmlrpc_value*, envP, &arrayP->_block, 0);
  519. if (envP->fault_occurred)
  520. free(arrayP);
  521. }
  522. *arrayPP = arrayP;
  523. }
  524. static void
  525. getArray(xmlrpc_env * const envP,
  526. const char ** const formatP,
  527. char const delimiter,
  528. va_list * const args,
  529. xmlrpc_value ** const arrayPP) {
  530. xmlrpc_value * arrayP;
  531. createXmlrpcArray(envP, &arrayP);
  532. /* Add items to the array until we hit our delimiter. */
  533. while (**formatP != delimiter && !envP->fault_occurred) {
  534. xmlrpc_value * itemP;
  535. if (**formatP == '\0')
  536. xmlrpc_env_set_fault(
  537. envP, XMLRPC_INTERNAL_ERROR,
  538. "format string ended before closing ')'.");
  539. else {
  540. getValue(envP, formatP, args, &itemP);
  541. if (!envP->fault_occurred) {
  542. xmlrpc_array_append_item(envP, arrayP, itemP);
  543. xmlrpc_DECREF(itemP);
  544. }
  545. }
  546. }
  547. if (envP->fault_occurred)
  548. xmlrpc_DECREF(arrayP);
  549. *arrayPP = arrayP;
  550. }
  551. static void
  552. getStructMember(xmlrpc_env * const envP,
  553. const char ** const formatP,
  554. va_list * const args,
  555. xmlrpc_value ** const keyPP,
  556. xmlrpc_value ** const valuePP) {
  557. /* Get the key */
  558. getValue(envP, formatP, args, keyPP);
  559. if (!envP->fault_occurred) {
  560. if (**formatP != ':')
  561. xmlrpc_env_set_fault(
  562. envP, XMLRPC_INTERNAL_ERROR,
  563. "format string does not have ':' after a "
  564. "structure member key.");
  565. else {
  566. /* Skip over colon that separates key from value */
  567. (*formatP)++;
  568. /* Get the value */
  569. getValue(envP, formatP, args, valuePP);
  570. }
  571. if (envP->fault_occurred)
  572. xmlrpc_DECREF(*keyPP);
  573. }
  574. }
  575. static void
  576. getStruct(xmlrpc_env * const envP,
  577. const char ** const formatP,
  578. char const delimiter,
  579. va_list * const args,
  580. xmlrpc_value ** const structPP) {
  581. xmlrpc_value * structP;
  582. structP = xmlrpc_struct_new(envP);
  583. if (!envP->fault_occurred) {
  584. while (**formatP != delimiter && !envP->fault_occurred) {
  585. xmlrpc_value * keyP;
  586. xmlrpc_value * valueP;
  587. getStructMember(envP, formatP, args, &keyP, &valueP);
  588. if (!envP->fault_occurred) {
  589. if (**formatP == ',')
  590. (*formatP)++; /* Skip over the comma */
  591. else if (**formatP == delimiter) {
  592. /* End of the line */
  593. } else
  594. xmlrpc_env_set_fault(
  595. envP, XMLRPC_INTERNAL_ERROR,
  596. "format string does not have ',' or ')' after "
  597. "a structure member");
  598. if (!envP->fault_occurred)
  599. /* Add the new member to the struct. */
  600. xmlrpc_struct_set_value_v(envP, structP, keyP, valueP);
  601. xmlrpc_DECREF(valueP);
  602. xmlrpc_DECREF(keyP);
  603. }
  604. }
  605. if (envP->fault_occurred)
  606. xmlrpc_DECREF(structP);
  607. }
  608. *structPP = structP;
  609. }
  610. static void
  611. getValue(xmlrpc_env * const envP,
  612. const char** const formatP,
  613. va_list * const args,
  614. xmlrpc_value ** const valPP) {
  615. /*----------------------------------------------------------------------------
  616. Get the next value from the list. *formatP points to the specifier
  617. for the next value in the format string (i.e. to the type code
  618. character) and we move *formatP past the whole specifier for the
  619. next value. We read the required arguments from 'args'. We return
  620. the value as *valPP with a reference to it.
  621. For example, if *formatP points to the "i" in the string "sis",
  622. we read one argument from 'args' and return as *valP an integer whose
  623. value is the argument we read. We advance *formatP to point to the
  624. last 's' and advance 'args' to point to the argument that belongs to
  625. that 's'.
  626. -----------------------------------------------------------------------------*/
  627. char const formatChar = *(*formatP)++;
  628. switch (formatChar) {
  629. case 'i':
  630. mkInt(envP, (xmlrpc_int32) va_arg(*args, xmlrpc_int32), valPP);
  631. break;
  632. case 'b':
  633. mkBool(envP, (xmlrpc_bool) va_arg(*args, xmlrpc_bool), valPP);
  634. break;
  635. case 'd':
  636. mkDouble(envP, (double) va_arg(*args, va_double), valPP);
  637. break;
  638. case 's':
  639. getString(envP, formatP, args, valPP);
  640. break;
  641. case 'w':
  642. getWideString(envP, formatP, args, valPP);
  643. break;
  644. /* The code 't' is reserved for a better, time_t based
  645. implementation of dateTime conversion.
  646. */
  647. case '8':
  648. mkDatetime(envP, (char*) va_arg(*args, char*), valPP);
  649. break;
  650. case '6':
  651. getBase64(envP, args, valPP);
  652. break;
  653. case 'p':
  654. /* We might someday want to use the code 'p!' to read in a
  655. cleanup function for this pointer.
  656. */
  657. mkCPtr(envP, (void*) va_arg(*args, void*), valPP);
  658. break;
  659. case 'A':
  660. mkArrayFromVal(envP, (xmlrpc_value*) va_arg(*args, xmlrpc_value*),
  661. valPP);
  662. break;
  663. case 'S':
  664. mkStructFromVal(envP, (xmlrpc_value*) va_arg(*args, xmlrpc_value*),
  665. valPP);
  666. break;
  667. case 'V':
  668. *valPP = (xmlrpc_value*) va_arg(*args, xmlrpc_value*);
  669. xmlrpc_INCREF(*valPP);
  670. break;
  671. case '(':
  672. getArray(envP, formatP, ')', args, valPP);
  673. if (!envP->fault_occurred) {
  674. XMLRPC_ASSERT(**formatP == ')');
  675. (*formatP)++; /* Skip over closing parenthesis */
  676. }
  677. break;
  678. case '{':
  679. getStruct(envP, formatP, '}', args, valPP);
  680. if (!envP->fault_occurred) {
  681. XMLRPC_ASSERT(**formatP == '}');
  682. (*formatP)++; /* Skip over closing brace */
  683. }
  684. break;
  685. default: {
  686. const char * const badCharacter = xmlrpc_makePrintableChar(formatChar);
  687. xmlrpc_env_set_fault_formatted(
  688. envP, XMLRPC_INTERNAL_ERROR,
  689. "Unexpected character '%s' in format string", badCharacter);
  690. xmlrpc_strfree(badCharacter);
  691. }
  692. }
  693. }
  694. void
  695. xmlrpc_build_value_va(xmlrpc_env * const envP,
  696. const char * const format,
  697. va_list args,
  698. xmlrpc_value ** const valPP,
  699. const char ** const tailP) {
  700. const char * formatCursor;
  701. va_list args_copy;
  702. XMLRPC_ASSERT_ENV_OK(envP);
  703. XMLRPC_ASSERT(format != NULL);
  704. if (strlen(format) == 0)
  705. xmlrpc_env_set_fault_formatted(
  706. envP, XMLRPC_INTERNAL_ERROR, "Format string is empty.");
  707. else {
  708. formatCursor = &format[0];
  709. VA_LIST_COPY(args_copy, args);
  710. getValue(envP, &formatCursor, &args_copy, valPP);
  711. if (!envP->fault_occurred)
  712. XMLRPC_ASSERT_VALUE_OK(*valPP);
  713. *tailP = formatCursor;
  714. }
  715. }
  716. xmlrpc_value *
  717. xmlrpc_build_value(xmlrpc_env * const envP,
  718. const char * const format,
  719. ...) {
  720. va_list args;
  721. xmlrpc_value* retval;
  722. const char * suffix;
  723. va_start(args, format);
  724. xmlrpc_build_value_va(envP, format, args, &retval, &suffix);
  725. va_end(args);
  726. if (!envP->fault_occurred) {
  727. if (*suffix != '\0')
  728. xmlrpc_env_set_fault_formatted(
  729. envP, XMLRPC_INTERNAL_ERROR, "Junk after the argument "
  730. "specifier: '%s'. There must be exactly one arument.",
  731. suffix);
  732. if (envP->fault_occurred)
  733. xmlrpc_DECREF(retval);
  734. }
  735. return retval;
  736. }
  737. /*=========================================================================
  738. ** Parsing XML-RPC values.
  739. **=========================================================================
  740. ** Parse an XML-RPC value based on a format string. This code is heavily
  741. ** inspired by Py_BuildValue from Python 1.5.2.
  742. */
  743. /* Prototype for recursive invocation: */
  744. static void
  745. parsevalue(xmlrpc_env * const env,
  746. xmlrpc_value * const val,
  747. const char ** const format,
  748. va_list * args);
  749. static void
  750. parsearray(xmlrpc_env * const env,
  751. const xmlrpc_value * const array,
  752. const char ** const format,
  753. char const delimiter,
  754. va_list * args) {
  755. int size, i;
  756. xmlrpc_value *item;
  757. /* Fetch the array size. */
  758. size = xmlrpc_array_size(env, array);
  759. XMLRPC_FAIL_IF_FAULT(env);
  760. /* Loop over the items in the array. */
  761. for (i = 0; i < size; i++) {
  762. /* Bail out if the caller didn't care about the rest of the items. */
  763. if (**format == '*')
  764. break;
  765. item = xmlrpc_array_get_item(env, array, i);
  766. XMLRPC_FAIL_IF_FAULT(env);
  767. XMLRPC_ASSERT(**format != '\0');
  768. if (**format == delimiter)
  769. XMLRPC_FAIL(env, XMLRPC_INDEX_ERROR, "Too many items in array");
  770. parsevalue(env, item, format, args);
  771. XMLRPC_FAIL_IF_FAULT(env);
  772. }
  773. if (**format == '*')
  774. (*format)++;
  775. if (**format != delimiter)
  776. XMLRPC_FAIL(env, XMLRPC_INDEX_ERROR, "Not enough items in array");
  777. cleanup:
  778. return;
  779. }
  780. static void
  781. parsestruct(xmlrpc_env * const env,
  782. xmlrpc_value * const strct,
  783. const char ** const format,
  784. char const delimiter,
  785. va_list * args) {
  786. xmlrpc_value *key, *value;
  787. char *keystr;
  788. size_t keylen;
  789. /* Set up error handling preconditions. */
  790. key = NULL;
  791. /* Build the members of our struct. */
  792. while (**format != '*' && **format != delimiter && **format != '\0') {
  793. /* Get our key, and skip over the ':' character. Notice the
  794. ** sudden call to getValue--we're going in the opposite direction. */
  795. getValue(env, format, args, &key);
  796. XMLRPC_FAIL_IF_FAULT(env);
  797. XMLRPC_ASSERT(**format == ':');
  798. (*format)++;
  799. /* Look up the value for our key. */
  800. xmlrpc_parse_value(env, key, "s#", &keystr, &keylen);
  801. XMLRPC_FAIL_IF_FAULT(env);
  802. value = xmlrpc_struct_get_value_n(env, strct, keystr, keylen);
  803. XMLRPC_FAIL_IF_FAULT(env);
  804. /* Get our value, and skip over the ',' character (if present). */
  805. parsevalue(env, value, format, args);
  806. XMLRPC_FAIL_IF_FAULT(env);
  807. XMLRPC_ASSERT(**format == ',' || **format == delimiter);
  808. if (**format == ',')
  809. (*format)++;
  810. /* Release our reference, and restore our invariant. */
  811. xmlrpc_DECREF(key);
  812. key = NULL;
  813. }
  814. if (**format == '*') {
  815. (*format)++;
  816. if (**format != delimiter && **format != '\0')
  817. XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR,
  818. "* can appear only at the end "
  819. "of a structure format specifier");
  820. } else {
  821. /* Here we're supposed to fail if he didn't extract all the
  822. members. But we don't know how to determine whether he
  823. specified all the members, so we always fail.
  824. */
  825. XMLRPC_FAIL(env, XMLRPC_INTERNAL_ERROR, "You must specify '*' as the "
  826. "last member of a structure in a format specifier "
  827. "used for parsing an xmlrpc_value");
  828. }
  829. XMLRPC_ASSERT(**format == delimiter || **format == '\0');
  830. cleanup:
  831. if (key)
  832. xmlrpc_DECREF(key);
  833. }
  834. static void
  835. parsevalue(xmlrpc_env * const envP,
  836. xmlrpc_value * const valueP,
  837. const char ** const format,
  838. va_list * args) {
  839. char formatSpecChar;
  840. formatSpecChar = *(*format)++;
  841. switch (formatSpecChar) {
  842. case 'i':
  843. validateType(envP, valueP, XMLRPC_TYPE_INT);
  844. if (!envP->fault_occurred) {
  845. xmlrpc_int32 * const int32ptr =
  846. (xmlrpc_int32*) va_arg(*args, xmlrpc_int32*);
  847. *int32ptr = valueP->_value.i;
  848. }
  849. break;
  850. case 'b':
  851. validateType(envP, valueP, XMLRPC_TYPE_BOOL);
  852. if (!envP->fault_occurred) {
  853. xmlrpc_bool * const boolptr =
  854. (xmlrpc_bool*) va_arg(*args, xmlrpc_bool*);
  855. *boolptr = valueP->_value.b;
  856. }
  857. break;
  858. case 'd':
  859. validateType(envP, valueP, XMLRPC_TYPE_DOUBLE);
  860. if (!envP->fault_occurred) {
  861. double * const doubleptr = (double*) va_arg(*args, double*);
  862. *doubleptr = valueP->_value.d;
  863. }
  864. break;
  865. case 's':
  866. validateType(envP, valueP, XMLRPC_TYPE_STRING);
  867. if (!envP->fault_occurred) {
  868. char * const contents =
  869. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
  870. size_t const len = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1;
  871. char ** const strptr = (char**) va_arg(*args, char**);
  872. if (**format == '#') {
  873. size_t * const sizeptr = (size_t*) va_arg(*args, size_t**);
  874. (*format)++;
  875. *sizeptr = len;
  876. } else
  877. verifyNoNulls(envP, contents, len);
  878. *strptr = contents;
  879. }
  880. break;
  881. #ifdef HAVE_UNICODE_WCHAR
  882. case 'w':
  883. validateType(envP, valueP, XMLRPC_TYPE_STRING);
  884. if (!envP->fault_occurred) {
  885. if (!valueP->_wcs_block) {
  886. /* Allocate a wchar_t string if we don't have one. */
  887. char * const contents =
  888. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
  889. size_t const len =
  890. XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block) - 1;
  891. valueP->_wcs_block =
  892. xmlrpc_utf8_to_wcs(envP, contents, len + 1);
  893. }
  894. if (!envP->fault_occurred) {
  895. wchar_t * const wcontents =
  896. XMLRPC_MEMBLOCK_CONTENTS(wchar_t, valueP->_wcs_block);
  897. size_t const len =
  898. XMLRPC_MEMBLOCK_SIZE(wchar_t, valueP->_wcs_block) - 1;
  899. wchar_t ** const wcsptr = (wchar_t**) va_arg(*args, wchar_t**);
  900. if (**format == '#') {
  901. size_t * const sizeptr = (size_t*) va_arg(*args, size_t**);
  902. (*format)++;
  903. *sizeptr = len;
  904. } else
  905. verifyNoNullsW(envP, wcontents, len);
  906. *wcsptr = wcontents;
  907. }
  908. }
  909. break;
  910. #endif /* HAVE_UNICODE_WCHAR */
  911. case '8':
  912. /* The code 't' is reserved for a better, time_t based
  913. ** implementation of dateTime conversion. */
  914. validateType(envP, valueP, XMLRPC_TYPE_DATETIME);
  915. if (!envP->fault_occurred) {
  916. char * const contents =
  917. XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block);
  918. char ** const strptr = (char**) va_arg(*args, char**);
  919. *strptr = contents;
  920. }
  921. break;
  922. case '6':
  923. validateType(envP, valueP, XMLRPC_TYPE_BASE64);
  924. if (!envP->fault_occurred) {
  925. unsigned char * const bin_data =
  926. XMLRPC_MEMBLOCK_CONTENTS(unsigned char,
  927. &valueP->_block);
  928. size_t const len = XMLRPC_MEMBLOCK_SIZE(char, &valueP->_block);
  929. unsigned char ** const binptr =
  930. (unsigned char**) va_arg(*args, unsigned char**);
  931. size_t * const sizeptr = (size_t*) va_arg(*args, size_t**);
  932. *binptr = bin_data;
  933. *sizeptr = len;
  934. }
  935. break;
  936. case 'p':
  937. validateType(envP, valueP, XMLRPC_TYPE_C_PTR);
  938. if (!envP->fault_occurred) {
  939. void ** const voidptrptr = (void**) va_arg(*args, void**);
  940. *voidptrptr = valueP->_value.c_ptr;
  941. }
  942. break;
  943. case 'V': {
  944. xmlrpc_value ** const valptr =
  945. (xmlrpc_value**) va_arg(*args, xmlrpc_value**);
  946. *valptr = valueP;
  947. }
  948. break;
  949. case 'A':
  950. validateType(envP, valueP, XMLRPC_TYPE_ARRAY);
  951. if (!envP->fault_occurred) {
  952. xmlrpc_value ** const valptr =
  953. (xmlrpc_value**) va_arg(*args, xmlrpc_value**);
  954. *valptr = valueP;
  955. }
  956. break;
  957. case 'S':
  958. validateType(envP, valueP, XMLRPC_TYPE_STRUCT);
  959. if (!envP->fault_occurred) {
  960. xmlrpc_value ** const valptr =
  961. (xmlrpc_value**) va_arg(*args, xmlrpc_value**);
  962. *valptr = valueP;
  963. }
  964. break;
  965. case '(':
  966. validateType(envP, valueP, XMLRPC_TYPE_ARRAY);
  967. if (!envP->fault_occurred) {
  968. parsearray(envP, valueP, format, ')', args);
  969. (*format)++;
  970. }
  971. break;
  972. case '{':
  973. validateType(envP, valueP, XMLRPC_TYPE_STRUCT);
  974. if (!envP->fault_occurred) {
  975. parsestruct(envP, valueP, format, '}', args);
  976. (*format)++;
  977. }
  978. break;
  979. default:
  980. xmlrpc_env_set_fault_formatted(
  981. envP, XMLRPC_INTERNAL_ERROR, "Invalid format character '%c'",
  982. formatSpecChar);
  983. }
  984. }
  985. void
  986. xmlrpc_parse_value_va(xmlrpc_env * const envP,
  987. xmlrpc_value * const value,
  988. const char * const format,
  989. va_list args) {
  990. const char *format_copy;
  991. va_list args_copy;
  992. XMLRPC_ASSERT_ENV_OK(envP);
  993. XMLRPC_ASSERT_VALUE_OK(value);
  994. XMLRPC_ASSERT(format != NULL);
  995. format_copy = format;
  996. VA_LIST_COPY(args_copy, args);
  997. parsevalue(envP, value, &format_copy, &args_copy);
  998. if (!envP->fault_occurred) {
  999. XMLRPC_ASSERT(*format_copy == '\0');
  1000. }
  1001. }
  1002. void
  1003. xmlrpc_parse_value(xmlrpc_env * const envP,
  1004. xmlrpc_value * const value,
  1005. const char * const format,
  1006. ...) {
  1007. va_list args;
  1008. va_start(args, format);
  1009. xmlrpc_parse_value_va(envP, value, format, args);
  1010. va_end(args);
  1011. }
  1012. /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
  1013. ** Copyright (C) 2001 by Eric Kidd. All rights reserved.
  1014. **
  1015. ** Redistribution and use in source and binary forms, with or without
  1016. ** modification, are permitted provided that the following conditions
  1017. ** are met:
  1018. ** 1. Redistributions of source code must retain the above copyright
  1019. ** notice, this list of conditions and the following disclaimer.
  1020. ** 2. Redistributions in binary form must reproduce the above copyright
  1021. ** notice, this list of conditions and the following disclaimer in the
  1022. ** documentation and/or other materials provided with the distribution.
  1023. ** 3. The name of the author may not be used to endorse or promote products
  1024. ** derived from this software without specific prior written permission.
  1025. **
  1026. ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  1027. ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1028. ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1029. ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  1030. ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1031. ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1032. ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1033. ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1034. ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1035. ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1036. ** SUCH DAMAGE. */