PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/soap/php_encoding.c

http://github.com/infusion/PHP
C | 3772 lines | 3250 code | 398 blank | 124 comment | 1283 complexity | 86b7d113740c1890487e1431a8153e13 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Brad Lafountain <rodif_bl@yahoo.com> |
  16. | Shane Caraveo <shane@caraveo.com> |
  17. | Dmitry Stogov <dmitry@zend.com> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id: php_encoding.c 306939 2011-01-01 02:19:59Z felipe $ */
  21. #include <time.h>
  22. #include "php_soap.h"
  23. #include "ext/libxml/php_libxml.h"
  24. #include "ext/standard/base64.h"
  25. #include <libxml/parserInternals.h>
  26. #include "zend_strtod.h"
  27. #include "zend_interfaces.h"
  28. /* zval type decode */
  29. static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data);
  30. static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data);
  31. static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data);
  32. static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data);
  33. static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data);
  34. static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data);
  35. static zval *to_zval_map(encodeTypePtr type, xmlNodePtr data);
  36. static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data);
  37. static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data);
  38. static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data);
  39. static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  40. static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  41. static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  42. /* String encode */
  43. static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  44. static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  45. static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  46. /* Null encode */
  47. static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  48. /* Array encode */
  49. static xmlNodePtr guess_array_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  50. static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  51. static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent);
  52. static xmlNodePtr to_xml_list1(encodeTypePtr enc, zval *data, int style, xmlNodePtr parent);
  53. /* Datetime encode/decode */
  54. static xmlNodePtr to_xml_datetime_ex(encodeTypePtr type, zval *data, char *format, int style, xmlNodePtr parent);
  55. static xmlNodePtr to_xml_datetime(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  56. static xmlNodePtr to_xml_time(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  57. static xmlNodePtr to_xml_date(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  58. static xmlNodePtr to_xml_gyearmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  59. static xmlNodePtr to_xml_gyear(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  60. static xmlNodePtr to_xml_gmonthday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  61. static xmlNodePtr to_xml_gday(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  62. static xmlNodePtr to_xml_gmonth(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  63. static xmlNodePtr to_xml_duration(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  64. static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data);
  65. static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data);
  66. static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  67. static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  68. static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data);
  69. static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  70. /* Try and guess for non-wsdl clients and servers */
  71. static zval *guess_zval_convert(encodeTypePtr type, xmlNodePtr data);
  72. static xmlNodePtr guess_xml_convert(encodeTypePtr type, zval *data, int style, xmlNodePtr parent);
  73. static int is_map(zval *array);
  74. static encodePtr get_array_type(xmlNodePtr node, zval *array, smart_str *out_type TSRMLS_DC);
  75. static xmlNodePtr check_and_resolve_href(xmlNodePtr data);
  76. static void set_ns_prop(xmlNodePtr node, char *ns, char *name, char *val);
  77. static void set_xsi_nil(xmlNodePtr node);
  78. static void set_xsi_type(xmlNodePtr node, char *type);
  79. static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret);
  80. static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type);
  81. static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type);
  82. #define FIND_XML_NULL(xml,zval) \
  83. { \
  84. xmlAttrPtr null; \
  85. if (!xml) { \
  86. ZVAL_NULL(zval); \
  87. return zval; \
  88. } \
  89. if (xml->properties) { \
  90. null = get_attribute(xml->properties, "nil"); \
  91. if (null) { \
  92. ZVAL_NULL(zval); \
  93. return zval; \
  94. } \
  95. } \
  96. }
  97. #define FIND_ZVAL_NULL(zval, xml, style) \
  98. { \
  99. if (!zval || Z_TYPE_P(zval) == IS_NULL) { \
  100. if (style == SOAP_ENCODED) {\
  101. set_xsi_nil(xml); \
  102. } \
  103. return xml; \
  104. } \
  105. }
  106. encode defaultEncoding[] = {
  107. {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert},
  108. {{IS_NULL, "nil", XSI_NAMESPACE, NULL}, to_zval_null, to_xml_null},
  109. {{IS_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
  110. {{IS_LONG, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  111. {{IS_DOUBLE, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
  112. {{IS_BOOL, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
  113. {{IS_CONSTANT, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
  114. {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map},
  115. {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
  116. {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
  117. {{IS_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, guess_array_map},
  118. {{IS_CONSTANT_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
  119. {{IS_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
  120. {{XSD_STRING, XSD_STRING_STRING, XSD_NAMESPACE, NULL}, to_zval_string, to_xml_string},
  121. {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
  122. {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  123. {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
  124. {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_NAMESPACE, NULL}, to_zval_double, to_xml_double},
  125. {{XSD_DATETIME, XSD_DATETIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_datetime},
  126. {{XSD_TIME, XSD_TIME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_time},
  127. {{XSD_DATE, XSD_DATE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_date},
  128. {{XSD_GYEARMONTH, XSD_GYEARMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyearmonth},
  129. {{XSD_GYEAR, XSD_GYEAR_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gyear},
  130. {{XSD_GMONTHDAY, XSD_GMONTHDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonthday},
  131. {{XSD_GDAY, XSD_GDAY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gday},
  132. {{XSD_GMONTH, XSD_GMONTH_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_gmonth},
  133. {{XSD_DURATION, XSD_DURATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_duration},
  134. {{XSD_HEXBINARY, XSD_HEXBINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_hexbin, to_xml_hexbin},
  135. {{XSD_BASE64BINARY, XSD_BASE64BINARY_STRING, XSD_NAMESPACE, NULL}, to_zval_base64, to_xml_base64},
  136. {{XSD_LONG, XSD_LONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  137. {{XSD_INT, XSD_INT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  138. {{XSD_SHORT, XSD_SHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  139. {{XSD_BYTE, XSD_BYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  140. {{XSD_NONPOSITIVEINTEGER, XSD_NONPOSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  141. {{XSD_POSITIVEINTEGER, XSD_POSITIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  142. {{XSD_NONNEGATIVEINTEGER, XSD_NONNEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  143. {{XSD_NEGATIVEINTEGER, XSD_NEGATIVEINTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  144. {{XSD_UNSIGNEDBYTE, XSD_UNSIGNEDBYTE_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  145. {{XSD_UNSIGNEDSHORT, XSD_UNSIGNEDSHORT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  146. {{XSD_UNSIGNEDINT, XSD_UNSIGNEDINT_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  147. {{XSD_UNSIGNEDLONG, XSD_UNSIGNEDLONG_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  148. {{XSD_INTEGER, XSD_INTEGER_STRING, XSD_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  149. {{XSD_ANYTYPE, XSD_ANYTYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert},
  150. {{XSD_UR_TYPE, XSD_UR_TYPE_STRING, XSD_NAMESPACE, NULL}, guess_zval_convert, guess_xml_convert},
  151. {{XSD_ANYURI, XSD_ANYURI_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  152. {{XSD_QNAME, XSD_QNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  153. {{XSD_NOTATION, XSD_NOTATION_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  154. {{XSD_NORMALIZEDSTRING, XSD_NORMALIZEDSTRING_STRING, XSD_NAMESPACE, NULL}, to_zval_stringr, to_xml_string},
  155. {{XSD_TOKEN, XSD_TOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  156. {{XSD_LANGUAGE, XSD_LANGUAGE_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  157. {{XSD_NMTOKEN, XSD_NMTOKEN_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  158. {{XSD_NMTOKENS, XSD_NMTOKENS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
  159. {{XSD_NAME, XSD_NAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  160. {{XSD_NCNAME, XSD_NCNAME_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  161. {{XSD_ID, XSD_ID_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  162. {{XSD_IDREF, XSD_IDREF_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  163. {{XSD_IDREFS, XSD_IDREFS_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
  164. {{XSD_ENTITY, XSD_ENTITY_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  165. {{XSD_ENTITIES, XSD_ENTITIES_STRING, XSD_NAMESPACE, NULL}, to_zval_stringc, to_xml_list1},
  166. {{APACHE_MAP, APACHE_MAP_STRING, APACHE_NAMESPACE, NULL}, to_zval_map, to_xml_map},
  167. {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
  168. {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_1_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
  169. {{SOAP_ENC_OBJECT, SOAP_ENC_OBJECT_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_object, to_xml_object},
  170. {{SOAP_ENC_ARRAY, SOAP_ENC_ARRAY_STRING, SOAP_1_2_ENC_NAMESPACE, NULL}, to_zval_array, to_xml_array},
  171. /* support some of the 1999 data types */
  172. {{XSD_STRING, XSD_STRING_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_string, to_xml_string},
  173. {{XSD_BOOLEAN, XSD_BOOLEAN_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_bool, to_xml_bool},
  174. {{XSD_DECIMAL, XSD_DECIMAL_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  175. {{XSD_FLOAT, XSD_FLOAT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double},
  176. {{XSD_DOUBLE, XSD_DOUBLE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_double, to_xml_double},
  177. {{XSD_LONG, XSD_LONG_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  178. {{XSD_INT, XSD_INT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  179. {{XSD_SHORT, XSD_SHORT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  180. {{XSD_BYTE, XSD_BYTE_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_long, to_xml_long},
  181. {{XSD_1999_TIMEINSTANT, XSD_1999_TIMEINSTANT_STRING, XSD_1999_NAMESPACE, NULL}, to_zval_stringc, to_xml_string},
  182. {{XSD_ANYXML, "<anyXML>", "<anyXML>", NULL}, to_zval_any, to_xml_any},
  183. {{END_KNOWN_TYPES, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert}
  184. };
  185. int numDefaultEncodings = sizeof(defaultEncoding)/sizeof(encode);
  186. void whiteSpace_replace(xmlChar* str)
  187. {
  188. while (*str != '\0') {
  189. if (*str == '\x9' || *str == '\xA' || *str == '\xD') {
  190. *str = ' ';
  191. }
  192. str++;
  193. }
  194. }
  195. void whiteSpace_collapse(xmlChar* str)
  196. {
  197. xmlChar *pos;
  198. xmlChar old;
  199. pos = str;
  200. whiteSpace_replace(str);
  201. while (*str == ' ') {
  202. str++;
  203. }
  204. old = '\0';
  205. while (*str != '\0') {
  206. if (*str != ' ' || old != ' ') {
  207. *pos = *str;
  208. pos++;
  209. }
  210. old = *str;
  211. str++;
  212. }
  213. if (old == ' ') {
  214. --pos;
  215. }
  216. *pos = '\0';
  217. }
  218. static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
  219. {
  220. if (sdl && sdl->encoders) {
  221. HashPosition pos;
  222. encodePtr *enc;
  223. for (zend_hash_internal_pointer_reset_ex(sdl->encoders, &pos);
  224. zend_hash_get_current_data_ex(sdl->encoders, (void **) &enc, &pos) == SUCCESS;
  225. zend_hash_move_forward_ex(sdl->encoders, &pos)) {
  226. if (strcmp((*enc)->details.type_str, type) == 0) {
  227. return *enc;
  228. }
  229. }
  230. }
  231. return NULL;
  232. }
  233. static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
  234. xmlNodePtr *node_ptr;
  235. if (SOAP_GLOBAL(ref_map)) {
  236. if (Z_TYPE_P(data) == IS_OBJECT) {
  237. data = (zval*)zend_objects_get_address(data TSRMLS_CC);
  238. }
  239. if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node_ptr) == SUCCESS) {
  240. xmlAttrPtr attr = (*node_ptr)->properties;
  241. char *id;
  242. smart_str prefix = {0};
  243. if (*node_ptr == node) {
  244. return 0;
  245. }
  246. xmlNodeSetName(node, (*node_ptr)->name);
  247. xmlSetNs(node, (*node_ptr)->ns);
  248. if (SOAP_GLOBAL(soap_version) == SOAP_1_1) {
  249. while (1) {
  250. attr = get_attribute(attr, "id");
  251. if (attr == NULL || attr->ns == NULL) {
  252. break;
  253. }
  254. attr = attr->next;
  255. }
  256. if (attr) {
  257. id = (char*)attr->children->content;
  258. smart_str_appendc(&prefix, '#');
  259. smart_str_appends(&prefix, id);
  260. smart_str_0(&prefix);
  261. id = prefix.c;
  262. } else {
  263. SOAP_GLOBAL(cur_uniq_ref)++;
  264. smart_str_appendl(&prefix, "#ref", 4);
  265. smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
  266. smart_str_0(&prefix);
  267. id = prefix.c;
  268. xmlSetProp((*node_ptr), BAD_CAST("id"), BAD_CAST(id+1));
  269. }
  270. xmlSetProp(node, BAD_CAST("href"), BAD_CAST(id));
  271. } else {
  272. attr = get_attribute_ex(attr, "id", SOAP_1_2_ENC_NAMESPACE);
  273. if (attr) {
  274. id = (char*)attr->children->content;
  275. smart_str_appendc(&prefix, '#');
  276. smart_str_appends(&prefix, id);
  277. smart_str_0(&prefix);
  278. id = prefix.c;
  279. } else {
  280. SOAP_GLOBAL(cur_uniq_ref)++;
  281. smart_str_appendl(&prefix, "#ref", 4);
  282. smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
  283. smart_str_0(&prefix);
  284. id = prefix.c;
  285. set_ns_prop((*node_ptr), SOAP_1_2_ENC_NAMESPACE, "id", id+1);
  286. }
  287. set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id);
  288. }
  289. smart_str_free(&prefix);
  290. return 1;
  291. } else {
  292. zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL);
  293. }
  294. }
  295. return 0;
  296. }
  297. static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
  298. {
  299. zval **data_ptr;
  300. if (SOAP_GLOBAL(ref_map)) {
  301. if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
  302. if (*data != *data_ptr) {
  303. zval_ptr_dtor(data);
  304. *data = *data_ptr;
  305. Z_SET_ISREF_PP(data);
  306. Z_ADDREF_PP(data);
  307. return 1;
  308. }
  309. } else {
  310. zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL);
  311. }
  312. }
  313. return 0;
  314. }
  315. static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xmlNodePtr parent, int check_class_map)
  316. {
  317. xmlNodePtr node = NULL;
  318. int add_type = 0;
  319. TSRMLS_FETCH();
  320. /* Special handling of class SoapVar */
  321. if (data &&
  322. Z_TYPE_P(data) == IS_OBJECT &&
  323. Z_OBJCE_P(data) == soap_var_class_entry) {
  324. zval **ztype, **zdata, **zns, **zstype, **zname, **znamens;
  325. encodePtr enc = NULL;
  326. HashTable *ht = Z_OBJPROP_P(data);
  327. if (zend_hash_find(ht, "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
  328. soap_error0(E_ERROR, "Encoding: SoapVar has no 'enc_type' property");
  329. }
  330. if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
  331. if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
  332. enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
  333. } else {
  334. zns = NULL;
  335. enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
  336. }
  337. if (enc == NULL && SOAP_GLOBAL(typemap)) {
  338. encodePtr *new_enc;
  339. smart_str nscat = {0};
  340. if (zns != NULL) {
  341. smart_str_appendl(&nscat, Z_STRVAL_PP(zns), Z_STRLEN_PP(zns));
  342. smart_str_appendc(&nscat, ':');
  343. }
  344. smart_str_appendl(&nscat, Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype));
  345. smart_str_0(&nscat);
  346. if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
  347. enc = *new_enc;
  348. }
  349. smart_str_free(&nscat);
  350. }
  351. }
  352. if (enc == NULL) {
  353. enc = get_conversion(Z_LVAL_P(*ztype));
  354. }
  355. if (enc == NULL) {
  356. enc = encode;
  357. }
  358. if (zend_hash_find(ht, "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) {
  359. node = master_to_xml(enc, NULL, style, parent);
  360. } else {
  361. node = master_to_xml(enc, *zdata, style, parent);
  362. }
  363. if (style == SOAP_ENCODED || (SOAP_GLOBAL(sdl) && encode != enc)) {
  364. if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
  365. if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
  366. set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
  367. } else {
  368. set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype));
  369. }
  370. }
  371. }
  372. if (zend_hash_find(ht, "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
  373. xmlNodeSetName(node, BAD_CAST(Z_STRVAL_PP(zname)));
  374. }
  375. if (zend_hash_find(ht, "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
  376. xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens));
  377. xmlSetNs(node, nsp);
  378. }
  379. } else {
  380. if (check_class_map && SOAP_GLOBAL(class_map) && data &&
  381. Z_TYPE_P(data) == IS_OBJECT &&
  382. !Z_OBJPROP_P(data)->nApplyCount) {
  383. zend_class_entry *ce = Z_OBJCE_P(data);
  384. HashPosition pos;
  385. zval **tmp;
  386. char *type_name = NULL;
  387. uint type_len;
  388. ulong idx;
  389. for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(class_map), &pos);
  390. zend_hash_get_current_data_ex(SOAP_GLOBAL(class_map), (void **) &tmp, &pos) == SUCCESS;
  391. zend_hash_move_forward_ex(SOAP_GLOBAL(class_map), &pos)) {
  392. if (Z_TYPE_PP(tmp) == IS_STRING &&
  393. ce->name_length == Z_STRLEN_PP(tmp) &&
  394. zend_binary_strncasecmp(ce->name, ce->name_length, Z_STRVAL_PP(tmp), ce->name_length, ce->name_length) == 0 &&
  395. zend_hash_get_current_key_ex(SOAP_GLOBAL(class_map), &type_name, &type_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
  396. /* TODO: namespace isn't stored */
  397. encodePtr enc = NULL;
  398. if (SOAP_GLOBAL(sdl)) {
  399. enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name);
  400. if (!enc) {
  401. enc = find_encoder_by_type_name(SOAP_GLOBAL(sdl), type_name);
  402. }
  403. }
  404. if (enc) {
  405. if (encode != enc && style == SOAP_LITERAL) {
  406. add_type = 1;
  407. }
  408. encode = enc;
  409. }
  410. break;
  411. }
  412. }
  413. }
  414. if (encode == NULL) {
  415. encode = get_conversion(UNKNOWN_TYPE);
  416. }
  417. if (SOAP_GLOBAL(typemap) && encode->details.type_str) {
  418. smart_str nscat = {0};
  419. encodePtr *new_enc;
  420. if (encode->details.ns) {
  421. smart_str_appends(&nscat, encode->details.ns);
  422. smart_str_appendc(&nscat, ':');
  423. }
  424. smart_str_appends(&nscat, encode->details.type_str);
  425. smart_str_0(&nscat);
  426. if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
  427. encode = *new_enc;
  428. }
  429. smart_str_free(&nscat);
  430. }
  431. if (encode->to_xml) {
  432. node = encode->to_xml(&encode->details, data, style, parent);
  433. if (add_type) {
  434. set_ns_and_type(node, &encode->details);
  435. }
  436. }
  437. }
  438. return node;
  439. }
  440. xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent)
  441. {
  442. return master_to_xml_int(encode, data, style, parent, 1);
  443. }
  444. static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data)
  445. {
  446. zval *ret = NULL;
  447. TSRMLS_FETCH();
  448. if (SOAP_GLOBAL(typemap)) {
  449. if (encode->details.type_str) {
  450. smart_str nscat = {0};
  451. encodePtr *new_enc;
  452. if (encode->details.ns) {
  453. smart_str_appends(&nscat, encode->details.ns);
  454. smart_str_appendc(&nscat, ':');
  455. }
  456. smart_str_appends(&nscat, encode->details.type_str);
  457. smart_str_0(&nscat);
  458. if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
  459. encode = *new_enc;
  460. }
  461. smart_str_free(&nscat);
  462. } else {
  463. xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
  464. if (type_attr != NULL) {
  465. encodePtr *new_enc;
  466. xmlNsPtr nsptr;
  467. char *ns, *cptype;
  468. smart_str nscat = {0};
  469. parse_namespace(type_attr->children->content, &cptype, &ns);
  470. nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns));
  471. if (nsptr != NULL) {
  472. smart_str_appends(&nscat, (char*)nsptr->href);
  473. smart_str_appendc(&nscat, ':');
  474. }
  475. smart_str_appends(&nscat, cptype);
  476. smart_str_0(&nscat);
  477. efree(cptype);
  478. if (ns) {efree(ns);}
  479. if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) {
  480. encode = *new_enc;
  481. }
  482. smart_str_free(&nscat);
  483. }
  484. }
  485. }
  486. if (encode->to_zval) {
  487. ret = encode->to_zval(&encode->details, data);
  488. }
  489. return ret;
  490. }
  491. zval *master_to_zval(encodePtr encode, xmlNodePtr data)
  492. {
  493. TSRMLS_FETCH();
  494. data = check_and_resolve_href(data);
  495. if (encode == NULL) {
  496. encode = get_conversion(UNKNOWN_TYPE);
  497. } else {
  498. /* Use xsi:type if it is defined */
  499. xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE);
  500. if (type_attr != NULL) {
  501. encodePtr enc = get_encoder_from_prefix(SOAP_GLOBAL(sdl), data, type_attr->children->content);
  502. if (enc != NULL && enc != encode) {
  503. encodePtr tmp = enc;
  504. while (tmp &&
  505. tmp->details.sdl_type != NULL &&
  506. tmp->details.sdl_type->kind != XSD_TYPEKIND_COMPLEX) {
  507. if (enc == tmp->details.sdl_type->encode ||
  508. tmp == tmp->details.sdl_type->encode) {
  509. enc = NULL;
  510. break;
  511. }
  512. tmp = tmp->details.sdl_type->encode;
  513. }
  514. if (enc != NULL) {
  515. encode = enc;
  516. }
  517. }
  518. }
  519. }
  520. return master_to_zval_int(encode, data);
  521. }
  522. xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  523. {
  524. xmlNodePtr ret = NULL;
  525. zval *return_value;
  526. TSRMLS_FETCH();
  527. if (type && type->map && type->map->to_xml) {
  528. MAKE_STD_ZVAL(return_value);
  529. if (call_user_function(EG(function_table), NULL, type->map->to_xml, return_value, 1, &data TSRMLS_CC) == FAILURE) {
  530. soap_error0(E_ERROR, "Encoding: Error calling to_xml callback");
  531. }
  532. if (Z_TYPE_P(return_value) == IS_STRING) {
  533. xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
  534. if (doc && doc->children) {
  535. ret = xmlDocCopyNode(doc->children, parent->doc, 1);
  536. }
  537. xmlFreeDoc(doc);
  538. }
  539. zval_ptr_dtor(&return_value);
  540. }
  541. if (!ret) {
  542. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  543. }
  544. xmlAddChild(parent, ret);
  545. if (style == SOAP_ENCODED) {
  546. set_ns_and_type(ret, type);
  547. }
  548. return ret;
  549. }
  550. zval *to_zval_user(encodeTypePtr type, xmlNodePtr node)
  551. {
  552. zval *return_value;
  553. TSRMLS_FETCH();
  554. if (type && type->map && type->map->to_zval) {
  555. xmlBufferPtr buf;
  556. zval *data;
  557. xmlNodePtr copy;
  558. copy = xmlCopyNode(node, 1);
  559. buf = xmlBufferCreate();
  560. xmlNodeDump(buf, NULL, copy, 0, 0);
  561. MAKE_STD_ZVAL(data);
  562. ZVAL_STRING(data, (char*)xmlBufferContent(buf), 1);
  563. xmlBufferFree(buf);
  564. xmlFreeNode(copy);
  565. ALLOC_INIT_ZVAL(return_value);
  566. if (call_user_function(EG(function_table), NULL, type->map->to_zval, return_value, 1, &data TSRMLS_CC) == FAILURE) {
  567. soap_error0(E_ERROR, "Encoding: Error calling from_xml callback");
  568. }
  569. zval_ptr_dtor(&data);
  570. } else {
  571. ALLOC_INIT_ZVAL(return_value);
  572. }
  573. return return_value;
  574. }
  575. /* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */
  576. /* String encode/decode */
  577. static zval *to_zval_string(encodeTypePtr type, xmlNodePtr data)
  578. {
  579. zval *ret;
  580. MAKE_STD_ZVAL(ret);
  581. FIND_XML_NULL(data, ret);
  582. if (data && data->children) {
  583. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  584. TSRMLS_FETCH();
  585. if (SOAP_GLOBAL(encoding) != NULL) {
  586. xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
  587. xmlBufferPtr out = xmlBufferCreate();
  588. int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
  589. if (n >= 0) {
  590. ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
  591. } else {
  592. ZVAL_STRING(ret, (char*)data->children->content, 1);
  593. }
  594. xmlBufferFree(out);
  595. xmlBufferFree(in);
  596. } else {
  597. ZVAL_STRING(ret, (char*)data->children->content, 1);
  598. }
  599. } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
  600. ZVAL_STRING(ret, (char*)data->children->content, 1);
  601. } else {
  602. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  603. }
  604. } else {
  605. ZVAL_EMPTY_STRING(ret);
  606. }
  607. return ret;
  608. }
  609. static zval *to_zval_stringr(encodeTypePtr type, xmlNodePtr data)
  610. {
  611. zval *ret;
  612. MAKE_STD_ZVAL(ret);
  613. FIND_XML_NULL(data, ret);
  614. if (data && data->children) {
  615. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  616. TSRMLS_FETCH();
  617. whiteSpace_replace(data->children->content);
  618. if (SOAP_GLOBAL(encoding) != NULL) {
  619. xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
  620. xmlBufferPtr out = xmlBufferCreate();
  621. int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
  622. if (n >= 0) {
  623. ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
  624. } else {
  625. ZVAL_STRING(ret, (char*)data->children->content, 1);
  626. }
  627. xmlBufferFree(out);
  628. xmlBufferFree(in);
  629. } else {
  630. ZVAL_STRING(ret, (char*)data->children->content, 1);
  631. }
  632. } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
  633. ZVAL_STRING(ret, (char*)data->children->content, 1);
  634. } else {
  635. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  636. }
  637. } else {
  638. ZVAL_EMPTY_STRING(ret);
  639. }
  640. return ret;
  641. }
  642. static zval *to_zval_stringc(encodeTypePtr type, xmlNodePtr data)
  643. {
  644. zval *ret;
  645. MAKE_STD_ZVAL(ret);
  646. FIND_XML_NULL(data, ret);
  647. if (data && data->children) {
  648. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  649. TSRMLS_FETCH();
  650. whiteSpace_collapse(data->children->content);
  651. if (SOAP_GLOBAL(encoding) != NULL) {
  652. xmlBufferPtr in = xmlBufferCreateStatic(data->children->content, xmlStrlen(data->children->content));
  653. xmlBufferPtr out = xmlBufferCreate();
  654. int n = xmlCharEncOutFunc(SOAP_GLOBAL(encoding), out, in);
  655. if (n >= 0) {
  656. ZVAL_STRING(ret, (char*)xmlBufferContent(out), 1);
  657. } else {
  658. ZVAL_STRING(ret, (char*)data->children->content, 1);
  659. }
  660. xmlBufferFree(out);
  661. xmlBufferFree(in);
  662. } else {
  663. ZVAL_STRING(ret, (char*)data->children->content, 1);
  664. }
  665. } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
  666. ZVAL_STRING(ret, (char*)data->children->content, 1);
  667. } else {
  668. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  669. }
  670. } else {
  671. ZVAL_EMPTY_STRING(ret);
  672. }
  673. return ret;
  674. }
  675. static zval *to_zval_base64(encodeTypePtr type, xmlNodePtr data)
  676. {
  677. zval *ret;
  678. char *str;
  679. int str_len;
  680. MAKE_STD_ZVAL(ret);
  681. FIND_XML_NULL(data, ret);
  682. if (data && data->children) {
  683. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  684. whiteSpace_collapse(data->children->content);
  685. str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
  686. if (!str) {
  687. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  688. }
  689. ZVAL_STRINGL(ret, str, str_len, 0);
  690. } else if (data->children->type == XML_CDATA_SECTION_NODE && data->children->next == NULL) {
  691. str = (char*)php_base64_decode(data->children->content, strlen((char*)data->children->content), &str_len);
  692. if (!str) {
  693. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  694. }
  695. ZVAL_STRINGL(ret, str, str_len, 0);
  696. } else {
  697. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  698. }
  699. } else {
  700. ZVAL_EMPTY_STRING(ret);
  701. }
  702. return ret;
  703. }
  704. static zval *to_zval_hexbin(encodeTypePtr type, xmlNodePtr data)
  705. {
  706. zval *ret;
  707. unsigned char *str;
  708. int str_len, i, j;
  709. unsigned char c;
  710. MAKE_STD_ZVAL(ret);
  711. FIND_XML_NULL(data, ret);
  712. if (data && data->children) {
  713. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  714. whiteSpace_collapse(data->children->content);
  715. } else if (data->children->type != XML_CDATA_SECTION_NODE || data->children->next != NULL) {
  716. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  717. return ret;
  718. }
  719. str_len = strlen((char*)data->children->content) / 2;
  720. str = emalloc(str_len+1);
  721. for (i = j = 0; i < str_len; i++) {
  722. c = data->children->content[j++];
  723. if (c >= '0' && c <= '9') {
  724. str[i] = (c - '0') << 4;
  725. } else if (c >= 'a' && c <= 'f') {
  726. str[i] = (c - 'a' + 10) << 4;
  727. } else if (c >= 'A' && c <= 'F') {
  728. str[i] = (c - 'A' + 10) << 4;
  729. } else {
  730. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  731. }
  732. c = data->children->content[j++];
  733. if (c >= '0' && c <= '9') {
  734. str[i] |= c - '0';
  735. } else if (c >= 'a' && c <= 'f') {
  736. str[i] |= c - 'a' + 10;
  737. } else if (c >= 'A' && c <= 'F') {
  738. str[i] |= c - 'A' + 10;
  739. } else {
  740. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  741. }
  742. }
  743. str[str_len] = '\0';
  744. ZVAL_STRINGL(ret, (char*)str, str_len, 0);
  745. } else {
  746. ZVAL_EMPTY_STRING(ret);
  747. }
  748. return ret;
  749. }
  750. static xmlNodePtr to_xml_string(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  751. {
  752. xmlNodePtr ret, text;
  753. char *str;
  754. int new_len;
  755. TSRMLS_FETCH();
  756. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  757. xmlAddChild(parent, ret);
  758. FIND_ZVAL_NULL(data, ret, style);
  759. if (Z_TYPE_P(data) == IS_STRING) {
  760. str = estrndup(Z_STRVAL_P(data), Z_STRLEN_P(data));
  761. new_len = Z_STRLEN_P(data);
  762. } else {
  763. zval tmp = *data;
  764. zval_copy_ctor(&tmp);
  765. convert_to_string(&tmp);
  766. str = estrndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
  767. new_len = Z_STRLEN(tmp);
  768. zval_dtor(&tmp);
  769. }
  770. if (SOAP_GLOBAL(encoding) != NULL) {
  771. xmlBufferPtr in = xmlBufferCreateStatic(str, new_len);
  772. xmlBufferPtr out = xmlBufferCreate();
  773. int n = xmlCharEncInFunc(SOAP_GLOBAL(encoding), out, in);
  774. if (n >= 0) {
  775. efree(str);
  776. str = estrdup((char*)xmlBufferContent(out));
  777. new_len = n;
  778. }
  779. xmlBufferFree(out);
  780. xmlBufferFree(in);
  781. }
  782. if (!php_libxml_xmlCheckUTF8(BAD_CAST(str))) {
  783. char *err = emalloc(new_len + 8);
  784. char c;
  785. int i;
  786. memcpy(err, str, new_len+1);
  787. for (i = 0; (c = err[i++]);) {
  788. if ((c & 0x80) == 0) {
  789. } else if ((c & 0xe0) == 0xc0) {
  790. if ((err[i] & 0xc0) != 0x80) {
  791. break;
  792. }
  793. i++;
  794. } else if ((c & 0xf0) == 0xe0) {
  795. if ((err[i] & 0xc0) != 0x80 || (err[i+1] & 0xc0) != 0x80) {
  796. break;
  797. }
  798. i += 2;
  799. } else if ((c & 0xf8) == 0xf0) {
  800. if ((err[i] & 0xc0) != 0x80 || (err[i+1] & 0xc0) != 0x80 || (err[i+2] & 0xc0) != 0x80) {
  801. break;
  802. }
  803. i += 3;
  804. } else {
  805. break;
  806. }
  807. }
  808. if (c) {
  809. err[i-1] = '\\';
  810. err[i++] = 'x';
  811. err[i++] = ((unsigned char)c >> 4) + ((((unsigned char)c >> 4) > 9) ? ('a' - 10) : '0');
  812. err[i++] = (c & 15) + (((c & 15) > 9) ? ('a' - 10) : '0');
  813. err[i++] = '.';
  814. err[i++] = '.';
  815. err[i++] = '.';
  816. err[i++] = 0;
  817. }
  818. soap_error1(E_ERROR, "Encoding: string '%s' is not a valid utf-8 string", err);
  819. }
  820. text = xmlNewTextLen(BAD_CAST(str), new_len);
  821. xmlAddChild(ret, text);
  822. efree(str);
  823. if (style == SOAP_ENCODED) {
  824. set_ns_and_type(ret, type);
  825. }
  826. return ret;
  827. }
  828. static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  829. {
  830. xmlNodePtr ret, text;
  831. unsigned char *str;
  832. int str_len;
  833. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  834. xmlAddChild(parent, ret);
  835. FIND_ZVAL_NULL(data, ret, style);
  836. if (Z_TYPE_P(data) == IS_STRING) {
  837. str = php_base64_encode((unsigned char*)Z_STRVAL_P(data), Z_STRLEN_P(data), &str_len);
  838. text = xmlNewTextLen(str, str_len);
  839. xmlAddChild(ret, text);
  840. efree(str);
  841. } else {
  842. zval tmp = *data;
  843. zval_copy_ctor(&tmp);
  844. convert_to_string(&tmp);
  845. str = php_base64_encode((unsigned char*)Z_STRVAL(tmp), Z_STRLEN(tmp), &str_len);
  846. text = xmlNewTextLen(str, str_len);
  847. xmlAddChild(ret, text);
  848. efree(str);
  849. zval_dtor(&tmp);
  850. }
  851. if (style == SOAP_ENCODED) {
  852. set_ns_and_type(ret, type);
  853. }
  854. return ret;
  855. }
  856. static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  857. {
  858. static char hexconvtab[] = "0123456789ABCDEF";
  859. xmlNodePtr ret, text;
  860. unsigned char *str;
  861. zval tmp;
  862. int i, j;
  863. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  864. xmlAddChild(parent, ret);
  865. FIND_ZVAL_NULL(data, ret, style);
  866. if (Z_TYPE_P(data) != IS_STRING) {
  867. tmp = *data;
  868. zval_copy_ctor(&tmp);
  869. convert_to_string(&tmp);
  870. data = &tmp;
  871. }
  872. str = (unsigned char *) safe_emalloc(Z_STRLEN_P(data) * 2, sizeof(char), 1);
  873. for (i = j = 0; i < Z_STRLEN_P(data); i++) {
  874. str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) >> 4];
  875. str[j++] = hexconvtab[((unsigned char)Z_STRVAL_P(data)[i]) & 15];
  876. }
  877. str[j] = '\0';
  878. text = xmlNewTextLen(str, Z_STRLEN_P(data) * 2 * sizeof(char));
  879. xmlAddChild(ret, text);
  880. efree(str);
  881. if (data == &tmp) {
  882. zval_dtor(&tmp);
  883. }
  884. if (style == SOAP_ENCODED) {
  885. set_ns_and_type(ret, type);
  886. }
  887. return ret;
  888. }
  889. static zval *to_zval_double(encodeTypePtr type, xmlNodePtr data)
  890. {
  891. zval *ret;
  892. MAKE_STD_ZVAL(ret);
  893. FIND_XML_NULL(data, ret);
  894. if (data && data->children) {
  895. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  896. long lval;
  897. double dval;
  898. whiteSpace_collapse(data->children->content);
  899. switch (is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0)) {
  900. case IS_LONG:
  901. Z_TYPE_P(ret) = IS_DOUBLE;
  902. Z_DVAL_P(ret) = lval;
  903. break;
  904. case IS_DOUBLE:
  905. Z_TYPE_P(ret) = IS_DOUBLE;
  906. Z_DVAL_P(ret) = dval;
  907. break;
  908. default:
  909. if (strncasecmp((char*)data->children->content, "NaN", sizeof("NaN")-1) == 0) {
  910. ZVAL_DOUBLE(ret, php_get_nan());
  911. } else if (strncasecmp((char*)data->children->content, "INF", sizeof("INF")-1) == 0) {
  912. ZVAL_DOUBLE(ret, php_get_inf());
  913. } else if (strncasecmp((char*)data->children->content, "-INF", sizeof("-INF")-1) == 0) {
  914. ZVAL_DOUBLE(ret, -php_get_inf());
  915. } else {
  916. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  917. }
  918. }
  919. } else {
  920. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  921. }
  922. } else {
  923. ZVAL_NULL(ret);
  924. }
  925. return ret;
  926. }
  927. static zval *to_zval_long(encodeTypePtr type, xmlNodePtr data)
  928. {
  929. zval *ret;
  930. MAKE_STD_ZVAL(ret);
  931. FIND_XML_NULL(data, ret);
  932. if (data && data->children) {
  933. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  934. long lval;
  935. double dval;
  936. whiteSpace_collapse(data->children->content);
  937. errno = 0;
  938. switch ((Z_TYPE_P(ret) = is_numeric_string((char*)data->children->content, strlen((char*)data->children->content), &lval, &dval, 0))) {
  939. case IS_LONG:
  940. Z_LVAL_P(ret) = lval;
  941. break;
  942. case IS_DOUBLE:
  943. Z_DVAL_P(ret) = dval;
  944. break;
  945. default:
  946. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  947. }
  948. } else {
  949. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  950. }
  951. } else {
  952. ZVAL_NULL(ret);
  953. }
  954. return ret;
  955. }
  956. static xmlNodePtr to_xml_long(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  957. {
  958. xmlNodePtr ret;
  959. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  960. xmlAddChild(parent, ret);
  961. FIND_ZVAL_NULL(data, ret, style);
  962. if (Z_TYPE_P(data) == IS_DOUBLE) {
  963. char s[256];
  964. snprintf(s, sizeof(s), "%0.0F",floor(Z_DVAL_P(data)));
  965. xmlNodeSetContent(ret, BAD_CAST(s));
  966. } else {
  967. zval tmp = *data;
  968. zval_copy_ctor(&tmp);
  969. if (Z_TYPE(tmp) != IS_LONG) {
  970. convert_to_long(&tmp);
  971. }
  972. convert_to_string(&tmp);
  973. xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
  974. zval_dtor(&tmp);
  975. }
  976. if (style == SOAP_ENCODED) {
  977. set_ns_and_type(ret, type);
  978. }
  979. return ret;
  980. }
  981. static xmlNodePtr to_xml_double(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  982. {
  983. xmlNodePtr ret;
  984. zval tmp;
  985. char *str;
  986. TSRMLS_FETCH();
  987. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  988. xmlAddChild(parent, ret);
  989. FIND_ZVAL_NULL(data, ret, style);
  990. tmp = *data;
  991. if (Z_TYPE(tmp) != IS_DOUBLE) {
  992. zval_copy_ctor(&tmp);
  993. convert_to_double(&tmp);
  994. }
  995. str = (char *) safe_emalloc(EG(precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
  996. php_gcvt(Z_DVAL(tmp), EG(precision), '.', 'E', str);
  997. xmlNodeSetContentLen(ret, BAD_CAST(str), strlen(str));
  998. efree(str);
  999. if (style == SOAP_ENCODED) {
  1000. set_ns_and_type(ret, type);
  1001. }
  1002. return ret;
  1003. }
  1004. static zval *to_zval_bool(encodeTypePtr type, xmlNodePtr data)
  1005. {
  1006. zval *ret;
  1007. MAKE_STD_ZVAL(ret);
  1008. FIND_XML_NULL(data, ret);
  1009. if (data && data->children) {
  1010. if (data->children->type == XML_TEXT_NODE && data->children->next == NULL) {
  1011. whiteSpace_collapse(data->children->content);
  1012. if (stricmp((char*)data->children->content, "true") == 0 ||
  1013. stricmp((char*)data->children->content, "t") == 0 ||
  1014. strcmp((char*)data->children->content, "1") == 0) {
  1015. ZVAL_BOOL(ret, 1);
  1016. } else if (stricmp((char*)data->children->content, "false") == 0 ||
  1017. stricmp((char*)data->children->content, "f") == 0 ||
  1018. strcmp((char*)data->children->content, "0") == 0) {
  1019. ZVAL_BOOL(ret, 0);
  1020. } else {
  1021. ZVAL_STRING(ret, (char*)data->children->content, 1);
  1022. convert_to_boolean(ret);
  1023. }
  1024. } else {
  1025. soap_error0(E_ERROR, "Encoding: Violation of encoding rules");
  1026. }
  1027. } else {
  1028. ZVAL_NULL(ret);
  1029. }
  1030. return ret;
  1031. }
  1032. static xmlNodePtr to_xml_bool(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  1033. {
  1034. xmlNodePtr ret;
  1035. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1036. xmlAddChild(parent, ret);
  1037. FIND_ZVAL_NULL(data, ret, style);
  1038. if (zend_is_true(data)) {
  1039. xmlNodeSetContent(ret, BAD_CAST("true"));
  1040. } else {
  1041. xmlNodeSetContent(ret, BAD_CAST("false"));
  1042. }
  1043. if (style == SOAP_ENCODED) {
  1044. set_ns_and_type(ret, type);
  1045. }
  1046. return ret;
  1047. }
  1048. /* Null encode/decode */
  1049. static zval *to_zval_null(encodeTypePtr type, xmlNodePtr data)
  1050. {
  1051. zval *ret;
  1052. MAKE_STD_ZVAL(ret);
  1053. ZVAL_NULL(ret);
  1054. return ret;
  1055. }
  1056. static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
  1057. {
  1058. xmlNodePtr ret;
  1059. ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1060. xmlAddChild(parent, ret);
  1061. if (style == SOAP_ENCODED) {
  1062. set_xsi_nil(ret);
  1063. }
  1064. return ret;
  1065. }
  1066. static void set_zval_property(zval* object, char* name, zval* val TSRMLS_DC)
  1067. {
  1068. zend_class_entry *old_scope;
  1069. old_scope = EG(scope);
  1070. EG(scope) = Z_OBJCE_P(object);
  1071. #ifdef ZEND_ENGINE_2
  1072. Z_DELREF_P(val);
  1073. #endif
  1074. add_property_zval(object, name, val);
  1075. EG(scope) = old_scope;
  1076. }
  1077. static zval* get_zval_property(zval* object, char* name TSRMLS_DC)
  1078. {
  1079. if (Z_TYPE_P(object) == IS_OBJECT) {
  1080. zval member;
  1081. zval *data;
  1082. zend_class_entry *old_scope;
  1083. INIT_PZVAL(&member);
  1084. ZVAL_STRING(&member, name, 0);
  1085. old_scope = EG(scope);
  1086. EG(scope) = Z_OBJCE_P(object);
  1087. data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS TSRMLS_CC);
  1088. if (data == EG(uninitialized_zval_ptr)) {
  1089. /* Hack for bug #32455 */
  1090. zend_property_info *property_info;
  1091. property_info = zend_get_property_info(Z_OBJCE_P(object), &member, 1 TSRMLS_CC);
  1092. EG(scope) = old_scope;
  1093. if (property_info && zend_hash_quick_exists(Z_OBJPROP_P(object), property_info->name, property_info->name_length+1, property_info->h)) {
  1094. return data;
  1095. }
  1096. return NULL;
  1097. }
  1098. EG(scope) = old_scope;
  1099. return data;
  1100. } else if (Z_TYPE_P(object) == IS_ARRAY) {
  1101. zval **data_ptr;
  1102. if (zend_hash_find(Z_ARRVAL_P(object), name, strlen(name)+1, (void**)&data_ptr) == SUCCESS) {
  1103. return *data_ptr;
  1104. }
  1105. }
  1106. return NULL;
  1107. }
  1108. static void unset_zval_property(zval* object, char* name TSRMLS_DC)
  1109. {
  1110. if (Z_TYPE_P(object) == IS_OBJECT) {
  1111. zval member;
  1112. zend_class_entry *old_scope;
  1113. INIT_PZVAL(&member);
  1114. ZVAL_STRING(&member, name, 0);
  1115. old_scope = EG(scope);
  1116. EG(scope) = Z_OBJCE_P(object);
  1117. Z_OBJ_HT_P(object)->unset_property(object, &member TSRMLS_CC);
  1118. EG(scope) = old_scope;
  1119. } else if (Z_TYPE_P(object) == IS_ARRAY) {
  1120. zend_hash_del(Z_ARRVAL_P(object), name, strlen(name)+1);
  1121. }
  1122. }
  1123. static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC)
  1124. {
  1125. zval* any = NULL;
  1126. char* name = NULL;
  1127. while (node != NULL) {
  1128. if (get_zval_property(ret, (char*)node->name TSRMLS_CC) == NULL) {
  1129. zval* val = master_to_zval(get_conversion(XSD_ANYXML), node);
  1130. if (any && Z_TYPE_P(any) != IS_ARRAY) {
  1131. /* Convert into array */
  1132. zval *arr;
  1133. MAKE_STD_ZVAL(arr);
  1134. array_init(arr);
  1135. if (name) {
  1136. add_assoc_zval(arr, name, any);
  1137. } else {
  1138. add_next_index_zval(arr, any);
  1139. }
  1140. any = arr;
  1141. }
  1142. if (Z_TYPE_P(val) == IS_STRING && *Z_STRVAL_P(val) == '<') {
  1143. name = NULL;
  1144. while (node->next != NULL) {
  1145. zval* val2 = master_to_zval(get_conversion(XSD_ANYXML), node->next);
  1146. if (Z_TYPE_P(val2) != IS_STRING || *Z_STRVAL_P(val) != '<') {
  1147. break;
  1148. }
  1149. add_string_to_string(val, val, val2);
  1150. zval_ptr_dtor(&val2);
  1151. node = node->next;
  1152. }
  1153. } else {
  1154. name = (char*)node->name;
  1155. }
  1156. if (any == NULL) {
  1157. if (name) {
  1158. /* Convert into array */
  1159. zval *arr;
  1160. MAKE_STD_ZVAL(arr);
  1161. array_init(arr);
  1162. add_assoc_zval(arr, name, val);
  1163. any = arr;
  1164. name = NULL;
  1165. } else {
  1166. any = val;
  1167. }
  1168. } else {
  1169. /* Add array element */
  1170. if (name) {
  1171. zval **el;
  1172. if (zend_hash_find(Z_ARRVAL_P(any), name, strlen(name)+1, (void**)&el) == SUCCESS) {
  1173. if (Z_TYPE_PP(el) != IS_ARRAY) {
  1174. /* Convert into array */
  1175. zval *arr;
  1176. MAKE_STD_ZVAL(arr);
  1177. array_init(arr);
  1178. add_next_index_zval(arr, *el);
  1179. *el = arr;
  1180. }
  1181. add_next_index_zval(*el, val);
  1182. } else {
  1183. add_assoc_zval(any, name, val);
  1184. }
  1185. } else {
  1186. add_next_index_zval(any, val);
  1187. }
  1188. name = NULL;
  1189. }
  1190. }
  1191. node = node->next;
  1192. }
  1193. if (any) {
  1194. set_zval_property(ret, name ? name : "any", any TSRMLS_CC);
  1195. }
  1196. }
  1197. static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr data, sdlPtr sdl TSRMLS_DC)
  1198. {
  1199. switch (model->kind) {
  1200. case XSD_CONTENT_ELEMENT:
  1201. if (model->u.element->name) {
  1202. xmlNodePtr node = get_node(data->children, model->u.element->name);
  1203. if (node) {
  1204. zval *val;
  1205. xmlNodePtr r_node;
  1206. r_node = check_and_resolve_href(node);
  1207. if (r_node && r_node->children && r_node->children->content) {
  1208. if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)r_node->children->content) != 0) {
  1209. soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, r_node->children->content);
  1210. }
  1211. val = master_to_zval(model->u.element->encode, r_node);
  1212. } else if (model->u.element->fixed) {
  1213. xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1214. xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
  1215. val = master_to_zval(model->u.element->encode, dummy);
  1216. xmlFreeNode(dummy);
  1217. } else if (model->u.element->def && !model->u.element->nillable) {
  1218. xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1219. xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
  1220. val = master_to_zval(model->u.element->encode, dummy);
  1221. xmlFreeNode(dummy);
  1222. } else {
  1223. val = master_to_zval(model->u.element->encode, r_node);
  1224. }
  1225. if ((node = get_node(node->next, model->u.element->name)) != NULL) {
  1226. zval *array;
  1227. MAKE_STD_ZVAL(array);
  1228. array_init(array);
  1229. add_next_index_zval(array, val);
  1230. do {
  1231. if (node && node->children && node->children->content) {
  1232. if (model->u.element->fixed && strcmp(model->u.element->fixed, (char*)node->children->content) != 0) {
  1233. soap_error3(E_ERROR, "Encoding: Element '%s' has fixed value '%s' (value '%s' is not allowed)", model->u.element->name, model->u.element->fixed, node->children->content);
  1234. }
  1235. val = master_to_zval(model->u.element->encode, node);
  1236. } else if (model->u.element->fixed) {
  1237. xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1238. xmlNodeSetContent(dummy, BAD_CAST(model->u.element->fixed));
  1239. val = master_to_zval(model->u.element->encode, dummy);
  1240. xmlFreeNode(dummy);
  1241. } else if (model->u.element->def && !model->u.element->nillable) {
  1242. xmlNodePtr dummy = xmlNewNode(NULL, BAD_CAST("BOGUS"));
  1243. xmlNodeSetContent(dummy, BAD_CAST(model->u.element->def));
  1244. val = master_to_zval(model->u.element->encode, dummy);
  1245. xmlFreeNode(dummy);
  1246. } else {
  1247. val = master_to_zval(model->u.element->encode, node);
  1248. }
  1249. add_next_index_zval(array, val);
  1250. } while ((node = get_node(node->next, model->u.element->name)) != NULL);
  1251. val = array;
  1252. } else if ((Z_TYPE_P(val) != IS_NULL || !model->u.element->nillable) &&
  1253. (SOAP_GLOBAL(features) & SOAP_SINGLE_ELEMENT_ARRAYS) &&
  1254. (model->max_occurs == -1 || model->max_occurs > 1)) {
  1255. zval *array;
  1256. MAKE_STD_ZVAL(array);
  1257. array_init(array);
  1258. add_next_index_zval(array, val);
  1259. val = array;
  1260. }
  1261. set_zval_property(ret, model->u.element->name, val TSRMLS_CC);
  1262. }
  1263. }
  1264. break;
  1265. case XSD_CONTENT_ALL:
  1266. case XSD_CONTENT_SEQUENCE:
  1267. case XSD_CONTENT_CHOICE: {
  1268. sdlContentModelPtr *tmp;
  1269. HashPosition pos;
  1270. sdlContentModelPtr any = NULL;
  1271. zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
  1272. while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
  1273. if ((*tmp)->kind == XSD_CONTENT_ANY) {
  1274. any = *tmp;
  1275. } else {
  1276. model_to_zval_object(ret, *tmp, data, sdl TSRMLS_CC);
  1277. }
  1278. zend_hash_move_forward_ex(model->u.content, &pos);
  1279. }
  1280. if (any) {
  1281. model_to_zval_any(ret, data->children TSRMLS_CC);
  1282. }
  1283. break;
  1284. }
  1285. case XSD_CONTENT_GROUP:
  1286. model_to_zval_object(ret, model->u.group->model, data, sdl TSRMLS_CC);
  1287. break;
  1288. default:
  1289. break;
  1290. }
  1291. }
  1292. /* Struct encode/decode */
  1293. static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_entry *pce)
  1294. {
  1295. zval *ret;
  1296. xmlNodePtr trav;
  1297. sdlPtr sdl;
  1298. sdlTypePtr sdlType = type->sdl_type;
  1299. zend_class_entry *ce = ZEND_STANDARD_CLASS_DEF_PTR;
  1300. zval *redo_any = NULL;
  1301. TSRMLS_FETCH();
  1302. if (pce) {
  1303. ce = pce;
  1304. } else if (SOAP_GLOBAL(class_map) && type->type_str) {
  1305. zval **classname;
  1306. zend_class_entry *tmp;
  1307. if (zend_hash_find(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str)+1, (void**)&classname) == SUCCESS &&
  1308. Z_TYPE_PP(classname) == IS_STRING &&
  1309. (tmp = zend_fetch_class(Z_STRVAL_PP(classname), Z_STRLEN_PP(classname), ZEND_FETCH_CLASS_AUTO TSRMLS_CC)) != NULL) {
  1310. ce = tmp;
  1311. }
  1312. }
  1313. sdl = SOAP_GLOBAL(sdl);
  1314. if (sdlType) {
  1315. if (sdlType->kind == XSD_TYPEKIND_RESTRICTION &&
  1316. sdlType->encode && type != &sdlType->encode->details) {
  1317. encodePtr enc;
  1318. enc = sdlType->encode;
  1319. while (enc && enc->details.sdl_type &&
  1320. enc->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
  1321. enc->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
  1322. enc->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
  1323. enc = enc->details.sdl_type->encode;
  1324. }
  1325. if (enc) {
  1326. zval *base;
  1327. ALLOC_INIT_ZVAL(ret);
  1328. if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
  1329. return ret;
  1330. }
  1331. object_init_ex(ret, ce);
  1332. base = master_to_zval_int(enc, data);
  1333. set_zval_property(ret, "_", base TSRMLS_CC);
  1334. } else {
  1335. ALLOC_INIT_ZVAL(ret);
  1336. FIND_XML_NULL(data, ret);
  1337. if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
  1338. return ret;
  1339. }
  1340. object_init_ex(ret, ce);
  1341. }
  1342. } else if (sdlType->kind == XSD_TYPEKIND_EXTENSION &&
  1343. sdlType->encode &&
  1344. type != &sdlType->encode->details) {
  1345. if (sdlType->encode->details.sdl_type &&
  1346. sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
  1347. sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
  1348. sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
  1349. if (ce != ZEND_STANDARD_CLASS_DEF_PTR &&
  1350. sdlType->encode->to_zval == sdl_guess_convert_zval &&
  1351. sdlType->encode->details.sdl_type != NULL &&
  1352. (sdlType->encode->details.sdl_ty

Large files files are truncated, but you can click here to view the full file