1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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_schema.c 287425 2009-08-17 18:23:48Z dmitry $ */
21 :
22 : #include "php_soap.h"
23 : #include "libxml/uri.h"
24 :
25 : static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type);
26 : static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type);
27 : static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type);
28 : static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type);
29 : static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type);
30 : static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType);
31 : static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type);
32 : static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
33 : static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
34 : static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model);
35 : static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
36 : static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model);
37 : static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model);
38 : static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
39 : static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model);
40 : static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
41 : static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
42 :
43 : static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr);
44 :
45 : static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr);
46 :
47 : static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type);
48 :
49 : static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
50 5333 : {
51 5333 : smart_str nscat = {0};
52 : encodePtr enc, *enc_ptr;
53 :
54 5333 : if (sdl->encoders == NULL) {
55 560 : sdl->encoders = emalloc(sizeof(HashTable));
56 560 : zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
57 : }
58 5333 : smart_str_appends(&nscat, (char*)ns);
59 5333 : smart_str_appendc(&nscat, ':');
60 5333 : smart_str_appends(&nscat, (char*)type);
61 5333 : smart_str_0(&nscat);
62 5333 : if (zend_hash_find(sdl->encoders, nscat.c, nscat.len + 1, (void**)&enc_ptr) == SUCCESS) {
63 1607 : enc = *enc_ptr;
64 1607 : if (enc->details.ns) {
65 1607 : efree(enc->details.ns);
66 : }
67 1607 : if (enc->details.type_str) {
68 1607 : efree(enc->details.type_str);
69 : }
70 : } else {
71 3726 : enc_ptr = NULL;
72 3726 : enc = emalloc(sizeof(encode));
73 : }
74 5333 : memset(enc, 0, sizeof(encode));
75 :
76 5333 : enc->details.ns = estrdup((char*)ns);
77 5333 : enc->details.type_str = estrdup((char*)type);
78 5333 : enc->details.sdl_type = cur_type;
79 5333 : enc->to_xml = sdl_guess_convert_xml;
80 5333 : enc->to_zval = sdl_guess_convert_zval;
81 :
82 5333 : if (enc_ptr == NULL) {
83 3726 : zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
84 : }
85 5333 : smart_str_free(&nscat);
86 5333 : return enc;
87 : }
88 :
89 : static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
90 12705 : {
91 12705 : encodePtr enc = get_encoder(sdl, (char*)ns, (char*)type);
92 12705 : if (enc == NULL) {
93 1619 : enc = create_encoder(sdl, cur_type, ns, type);
94 : }
95 12705 : return enc;
96 : }
97 :
98 1143 : static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import TSRMLS_DC) {
99 1143 : if (location != NULL &&
100 : !zend_hash_exists(&ctx->docs, (char*)location, xmlStrlen(location)+1)) {
101 : xmlDocPtr doc;
102 : xmlNodePtr schema;
103 : xmlAttrPtr new_tns;
104 :
105 4 : sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC);
106 4 : doc = soap_xmlParseFile((char*)location TSRMLS_CC);
107 4 : sdl_restore_uri_credentials(ctx TSRMLS_CC);
108 :
109 4 : if (doc == NULL) {
110 0 : soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
111 : }
112 4 : schema = get_node(doc->children, "schema");
113 4 : if (schema == NULL) {
114 0 : xmlFreeDoc(doc);
115 0 : soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
116 : }
117 4 : new_tns = get_attribute(schema->properties, "targetNamespace");
118 4 : if (import) {
119 4 : if (ns != NULL && (new_tns == NULL || xmlStrcmp(ns->children->content, new_tns->children->content) != 0)) {
120 0 : xmlFreeDoc(doc);
121 0 : soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, ns->children->content);
122 : }
123 4 : if (ns == NULL && new_tns != NULL) {
124 0 : xmlFreeDoc(doc);
125 0 : soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, new_tns->children->content);
126 : }
127 : } else {
128 0 : new_tns = get_attribute(schema->properties, "targetNamespace");
129 0 : if (new_tns == NULL) {
130 0 : if (tns != NULL) {
131 0 : xmlSetProp(schema, BAD_CAST("targetNamespace"), tns->children->content);
132 : }
133 0 : } else if (tns != NULL && xmlStrcmp(tns->children->content, new_tns->children->content) != 0) {
134 0 : xmlFreeDoc(doc);
135 0 : soap_error1(E_ERROR, "Parsing Schema: can't include schema from '%s', different 'targetNamespace'", location);
136 : }
137 : }
138 4 : zend_hash_add(&ctx->docs, (char*)location, xmlStrlen(location)+1, (void**)&doc, sizeof(xmlDocPtr), NULL);
139 4 : load_schema(ctx, schema TSRMLS_CC);
140 : }
141 1143 : }
142 :
143 : /*
144 : 2.6.1 xsi:type
145 : 2.6.2 xsi:nil
146 : 2.6.3 xsi:schemaLocation, xsi:noNamespaceSchemaLocation
147 : */
148 :
149 : /*
150 : <schema
151 : attributeFormDefault = (qualified | unqualified) : unqualified
152 : blockDefault = (#all | List of (extension | restriction | substitution)) : ''
153 : elementFormDefault = (qualified | unqualified) : unqualified
154 : finalDefault = (#all | List of (extension | restriction)) : ''
155 : id = ID
156 : targetNamespace = anyURI
157 : version = token
158 : xml:lang = language
159 : {any attributes with non-schema namespace . . .}>
160 : Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
161 : </schema>
162 : */
163 : int load_schema(sdlCtx *ctx, xmlNodePtr schema TSRMLS_DC)
164 1105 : {
165 : xmlNodePtr trav;
166 : xmlAttrPtr tns;
167 :
168 1105 : if (!ctx->sdl->types) {
169 671 : ctx->sdl->types = emalloc(sizeof(HashTable));
170 671 : zend_hash_init(ctx->sdl->types, 0, NULL, delete_type, 0);
171 : }
172 1105 : if (!ctx->attributes) {
173 671 : ctx->attributes = emalloc(sizeof(HashTable));
174 671 : zend_hash_init(ctx->attributes, 0, NULL, delete_attribute, 0);
175 : }
176 1105 : if (!ctx->attributeGroups) {
177 671 : ctx->attributeGroups = emalloc(sizeof(HashTable));
178 671 : zend_hash_init(ctx->attributeGroups, 0, NULL, delete_type, 0);
179 : }
180 :
181 1105 : tns = get_attribute(schema->properties, "targetNamespace");
182 1105 : if (tns == NULL) {
183 3 : tns = xmlSetProp(schema, BAD_CAST("targetNamespace"), BAD_CAST(""));
184 3 : xmlNewNs(schema, BAD_CAST(""), NULL);
185 : }
186 :
187 1105 : trav = schema->children;
188 3360 : while (trav != NULL) {
189 2244 : if (node_is_equal(trav,"include")) {
190 : xmlAttrPtr location;
191 :
192 0 : location = get_attribute(trav->properties, "schemaLocation");
193 0 : if (location == NULL) {
194 0 : soap_error0(E_ERROR, "Parsing Schema: include has no 'schemaLocation' attribute");
195 : } else {
196 : xmlChar *uri;
197 0 : xmlChar *base = xmlNodeGetBase(trav->doc, trav);
198 :
199 0 : if (base == NULL) {
200 0 : uri = xmlBuildURI(location->children->content, trav->doc->URL);
201 : } else {
202 0 : uri = xmlBuildURI(location->children->content, base);
203 0 : xmlFree(base);
204 : }
205 0 : schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
206 0 : xmlFree(uri);
207 : }
208 :
209 2244 : } else if (node_is_equal(trav,"redefine")) {
210 : xmlAttrPtr location;
211 :
212 0 : location = get_attribute(trav->properties, "schemaLocation");
213 0 : if (location == NULL) {
214 0 : soap_error0(E_ERROR, "Parsing Schema: redefine has no 'schemaLocation' attribute");
215 : } else {
216 : xmlChar *uri;
217 0 : xmlChar *base = xmlNodeGetBase(trav->doc, trav);
218 :
219 0 : if (base == NULL) {
220 0 : uri = xmlBuildURI(location->children->content, trav->doc->URL);
221 : } else {
222 0 : uri = xmlBuildURI(location->children->content, base);
223 0 : xmlFree(base);
224 : }
225 0 : schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
226 0 : xmlFree(uri);
227 : /* TODO: <redefine> support */
228 : }
229 :
230 2244 : } else if (node_is_equal(trav,"import")) {
231 : xmlAttrPtr ns, location;
232 1143 : xmlChar *uri = NULL;
233 :
234 1143 : ns = get_attribute(trav->properties, "namespace");
235 1143 : location = get_attribute(trav->properties, "schemaLocation");
236 :
237 1143 : if (ns != NULL && tns != NULL && xmlStrcmp(ns->children->content, tns->children->content) == 0) {
238 0 : if (location) {
239 0 : soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s', namespace must not match the enclosing schema 'targetNamespace'", location->children->content);
240 : } else {
241 0 : soap_error0(E_ERROR, "Parsing Schema: can't import schema. Namespace must not match the enclosing schema 'targetNamespace'");
242 : }
243 : }
244 1143 : if (location) {
245 4 : xmlChar *base = xmlNodeGetBase(trav->doc, trav);
246 :
247 4 : if (base == NULL) {
248 0 : uri = xmlBuildURI(location->children->content, trav->doc->URL);
249 : } else {
250 4 : uri = xmlBuildURI(location->children->content, base);
251 4 : xmlFree(base);
252 : }
253 : }
254 1143 : schema_load_file(ctx, ns, uri, tns, 1 TSRMLS_CC);
255 1143 : if (uri != NULL) {xmlFree(uri);}
256 1101 : } else if (node_is_equal(trav,"annotation")) {
257 : /* TODO: <annotation> support */
258 : /* annotation cleanup
259 : xmlNodePtr tmp = trav;
260 : trav = trav->next;
261 : xmlUnlinkNode(tmp);
262 : xmlFreeNode(tmp);
263 : continue;
264 : */
265 : } else {
266 1094 : break;
267 : }
268 1150 : trav = trav->next;
269 : }
270 :
271 12363 : while (trav != NULL) {
272 10153 : if (node_is_equal(trav,"simpleType")) {
273 328 : schema_simpleType(ctx->sdl, tns, trav, NULL);
274 9825 : } else if (node_is_equal(trav,"complexType")) {
275 3386 : schema_complexType(ctx->sdl, tns, trav, NULL);
276 6439 : } else if (node_is_equal(trav,"group")) {
277 2 : schema_group(ctx->sdl, tns, trav, NULL, NULL);
278 6437 : } else if (node_is_equal(trav,"attributeGroup")) {
279 9 : schema_attributeGroup(ctx->sdl, tns, trav, NULL, ctx);
280 6428 : } else if (node_is_equal(trav,"element")) {
281 6410 : schema_element(ctx->sdl, tns, trav, NULL, NULL);
282 18 : } else if (node_is_equal(trav,"attribute")) {
283 18 : schema_attribute(ctx->sdl, tns, trav, NULL, ctx);
284 0 : } else if (node_is_equal(trav,"notation")) {
285 : /* TODO: <notation> support */
286 0 : } else if (node_is_equal(trav,"annotation")) {
287 : /* TODO: <annotation> support */
288 : } else {
289 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in schema", trav->name);
290 : }
291 10153 : trav = trav->next;
292 : }
293 1105 : return TRUE;
294 : }
295 :
296 : /*
297 : <simpleType
298 : final = (#all | (list | union | restriction))
299 : id = ID
300 : name = NCName
301 : {any attributes with non-schema namespace . . .}>
302 : Content: (annotation?, (restriction | list | union))
303 : </simpleType>
304 : */
305 : static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type)
306 388 : {
307 : xmlNodePtr trav;
308 : xmlAttrPtr name, ns;
309 :
310 388 : ns = get_attribute(simpleType->properties, "targetNamespace");
311 388 : if (ns == NULL) {
312 388 : ns = tns;
313 : }
314 :
315 388 : name = get_attribute(simpleType->properties, "name");
316 388 : if (cur_type != NULL) {
317 : /* Anonymous type inside <element> or <restriction> */
318 : sdlTypePtr newType, *ptr;
319 :
320 60 : newType = emalloc(sizeof(sdlType));
321 60 : memset(newType, 0, sizeof(sdlType));
322 60 : newType->kind = XSD_TYPEKIND_SIMPLE;
323 60 : if (name != NULL) {
324 8 : newType->name = estrdup((char*)name->children->content);
325 8 : newType->namens = estrdup((char*)ns->children->content);
326 : } else {
327 52 : newType->name = estrdup(cur_type->name);
328 52 : newType->namens = estrdup(cur_type->namens);
329 : }
330 :
331 60 : zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
332 :
333 60 : if (sdl->encoders == NULL) {
334 6 : sdl->encoders = emalloc(sizeof(HashTable));
335 6 : zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
336 : }
337 60 : cur_type->encode = emalloc(sizeof(encode));
338 60 : memset(cur_type->encode, 0, sizeof(encode));
339 60 : cur_type->encode->details.ns = estrdup(newType->namens);
340 60 : cur_type->encode->details.type_str = estrdup(newType->name);
341 60 : cur_type->encode->details.sdl_type = *ptr;
342 60 : cur_type->encode->to_xml = sdl_guess_convert_xml;
343 60 : cur_type->encode->to_zval = sdl_guess_convert_zval;
344 60 : zend_hash_next_index_insert(sdl->encoders, &cur_type->encode, sizeof(encodePtr), NULL);
345 :
346 60 : cur_type =*ptr;
347 :
348 328 : } else if (name != NULL) {
349 : sdlTypePtr newType, *ptr;
350 :
351 328 : newType = emalloc(sizeof(sdlType));
352 328 : memset(newType, 0, sizeof(sdlType));
353 328 : newType->kind = XSD_TYPEKIND_SIMPLE;
354 328 : newType->name = estrdup((char*)name->children->content);
355 328 : newType->namens = estrdup((char*)ns->children->content);
356 :
357 328 : if (cur_type == NULL) {
358 328 : zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
359 : } else {
360 0 : if (cur_type->elements == NULL) {
361 0 : cur_type->elements = emalloc(sizeof(HashTable));
362 0 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
363 : }
364 0 : zend_hash_update(cur_type->elements, newType->name, strlen(newType->name)+1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
365 : }
366 328 : cur_type = (*ptr);
367 :
368 328 : create_encoder(sdl, cur_type, ns->children->content, name->children->content);
369 : } else {
370 0 : soap_error0(E_ERROR, "Parsing Schema: simpleType has no 'name' attribute");
371 : }
372 :
373 388 : trav = simpleType->children;
374 388 : if (trav != NULL && node_is_equal(trav,"annotation")) {
375 : /* TODO: <annotation> support */
376 12 : trav = trav->next;
377 : }
378 388 : if (trav != NULL) {
379 388 : if (node_is_equal(trav,"restriction")) {
380 344 : schema_restriction_simpleContent(sdl, tns, trav, cur_type, 1);
381 344 : trav = trav->next;
382 44 : } else if (node_is_equal(trav,"list")) {
383 22 : cur_type->kind = XSD_TYPEKIND_LIST;
384 22 : schema_list(sdl, tns, trav, cur_type);
385 22 : trav = trav->next;
386 22 : } else if (node_is_equal(trav,"union")) {
387 22 : cur_type->kind = XSD_TYPEKIND_UNION;
388 22 : schema_union(sdl, tns, trav, cur_type);
389 22 : trav = trav->next;
390 : } else {
391 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
392 : }
393 : } else {
394 0 : soap_error0(E_ERROR, "Parsing Schema: expected <restriction>, <list> or <union> in simpleType");
395 : }
396 388 : if (trav != NULL) {
397 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
398 : }
399 :
400 388 : return TRUE;
401 : }
402 :
403 : /*
404 : <list
405 : id = ID
406 : itemType = QName
407 : {any attributes with non-schema namespace . . .}>
408 : Content: (annotation?, (simpleType?))
409 : </list>
410 : */
411 : static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type)
412 22 : {
413 : xmlNodePtr trav;
414 : xmlAttrPtr itemType;
415 :
416 22 : itemType = get_attribute(listType->properties, "itemType");
417 22 : if (itemType != NULL) {
418 : char *type, *ns;
419 : xmlNsPtr nsptr;
420 :
421 13 : parse_namespace(itemType->children->content, &type, &ns);
422 13 : nsptr = xmlSearchNs(listType->doc, listType, BAD_CAST(ns));
423 13 : if (nsptr != NULL) {
424 : sdlTypePtr newType, *tmp;
425 :
426 13 : newType = emalloc(sizeof(sdlType));
427 13 : memset(newType, 0, sizeof(sdlType));
428 :
429 13 : newType->name = estrdup(type);
430 13 : newType->namens = estrdup((char*)nsptr->href);
431 :
432 13 : newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
433 :
434 13 : if (cur_type->elements == NULL) {
435 13 : cur_type->elements = emalloc(sizeof(HashTable));
436 13 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
437 : }
438 13 : zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
439 : }
440 13 : if (type) {efree(type);}
441 13 : if (ns) {efree(ns);}
442 : }
443 :
444 22 : trav = listType->children;
445 22 : if (trav != NULL && node_is_equal(trav,"annotation")) {
446 : /* TODO: <annotation> support */
447 0 : trav = trav->next;
448 : }
449 22 : if (trav != NULL && node_is_equal(trav,"simpleType")) {
450 : sdlTypePtr newType, *tmp;
451 :
452 9 : if (itemType != NULL) {
453 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'itemType' attribute and subtype");
454 : }
455 :
456 9 : newType = emalloc(sizeof(sdlType));
457 9 : memset(newType, 0, sizeof(sdlType));
458 :
459 : {
460 9 : smart_str anonymous = {0};
461 :
462 9 : smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
463 9 : smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
464 9 : smart_str_0(&anonymous);
465 9 : newType->name = anonymous.c;
466 : }
467 9 : newType->namens = estrdup((char*)tns->children->content);
468 :
469 9 : if (cur_type->elements == NULL) {
470 9 : cur_type->elements = emalloc(sizeof(HashTable));
471 9 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
472 : }
473 9 : zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
474 :
475 9 : schema_simpleType(sdl, tns, trav, newType);
476 :
477 9 : trav = trav->next;
478 : }
479 22 : if (trav != NULL) {
480 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in list", trav->name);
481 : }
482 22 : return TRUE;
483 : }
484 :
485 : /*
486 : <union
487 : id = ID
488 : memberTypes = List of QName
489 : {any attributes with non-schema namespace . . .}>
490 : Content: (annotation?, (simpleType*))
491 : </union>
492 : */
493 : static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type)
494 22 : {
495 : xmlNodePtr trav;
496 : xmlAttrPtr memberTypes;
497 :
498 22 : memberTypes = get_attribute(unionType->properties, "memberTypes");
499 22 : if (memberTypes != NULL) {
500 : char *str, *start, *end, *next;
501 : char *type, *ns;
502 : xmlNsPtr nsptr;
503 :
504 10 : str = estrdup((char*)memberTypes->children->content);
505 10 : whiteSpace_collapse(BAD_CAST(str));
506 10 : start = str;
507 46 : while (start != NULL && *start != '\0') {
508 26 : end = strchr(start,' ');
509 26 : if (end == NULL) {
510 10 : next = NULL;
511 : } else {
512 16 : *end = '\0';
513 16 : next = end+1;
514 : }
515 :
516 26 : parse_namespace(BAD_CAST(start), &type, &ns);
517 26 : nsptr = xmlSearchNs(unionType->doc, unionType, BAD_CAST(ns));
518 26 : if (nsptr != NULL) {
519 : sdlTypePtr newType, *tmp;
520 :
521 26 : newType = emalloc(sizeof(sdlType));
522 26 : memset(newType, 0, sizeof(sdlType));
523 :
524 26 : newType->name = estrdup(type);
525 26 : newType->namens = estrdup((char*)nsptr->href);
526 :
527 26 : newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
528 :
529 26 : if (cur_type->elements == NULL) {
530 10 : cur_type->elements = emalloc(sizeof(HashTable));
531 10 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
532 : }
533 26 : zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
534 : }
535 26 : if (type) {efree(type);}
536 26 : if (ns) {efree(ns);}
537 :
538 26 : start = next;
539 : }
540 10 : efree(str);
541 : }
542 :
543 22 : trav = unionType->children;
544 22 : if (trav != NULL && node_is_equal(trav,"annotation")) {
545 : /* TODO: <annotation> support */
546 0 : trav = trav->next;
547 : }
548 74 : while (trav != NULL) {
549 30 : if (node_is_equal(trav,"simpleType")) {
550 : sdlTypePtr newType, *tmp;
551 :
552 30 : newType = emalloc(sizeof(sdlType));
553 30 : memset(newType, 0, sizeof(sdlType));
554 :
555 : {
556 30 : smart_str anonymous = {0};
557 :
558 30 : smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
559 30 : smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
560 30 : smart_str_0(&anonymous);
561 30 : newType->name = anonymous.c;
562 : }
563 30 : newType->namens = estrdup((char*)tns->children->content);
564 :
565 30 : if (cur_type->elements == NULL) {
566 12 : cur_type->elements = emalloc(sizeof(HashTable));
567 12 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
568 : }
569 30 : zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
570 :
571 30 : schema_simpleType(sdl, tns, trav, newType);
572 :
573 : } else {
574 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
575 : }
576 30 : trav = trav->next;
577 : }
578 22 : if (trav != NULL) {
579 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
580 : }
581 22 : return TRUE;
582 : }
583 :
584 : /*
585 : <simpleContent
586 : id = ID
587 : {any attributes with non-schema namespace . . .}>
588 : Content: (annotation?, (restriction | extension))
589 : </simpleContent>
590 : */
591 : static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type)
592 24 : {
593 : xmlNodePtr trav;
594 :
595 24 : trav = simpCompType->children;
596 24 : if (trav != NULL && node_is_equal(trav,"annotation")) {
597 : /* TODO: <annotation> support */
598 0 : trav = trav->next;
599 : }
600 24 : if (trav != NULL) {
601 24 : if (node_is_equal(trav, "restriction")) {
602 6 : cur_type->kind = XSD_TYPEKIND_RESTRICTION;
603 6 : schema_restriction_simpleContent(sdl, tns, trav, cur_type, 0);
604 6 : trav = trav->next;
605 18 : } else if (node_is_equal(trav, "extension")) {
606 18 : cur_type->kind = XSD_TYPEKIND_EXTENSION;
607 18 : schema_extension_simpleContent(sdl, tns, trav, cur_type);
608 18 : trav = trav->next;
609 : } else {
610 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
611 : }
612 : } else {
613 0 : soap_error0(E_ERROR, "Parsing Schema: expected <restriction> or <extension> in simpleContent");
614 : }
615 24 : if (trav != NULL) {
616 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
617 : }
618 :
619 24 : return TRUE;
620 : }
621 :
622 : /*
623 : simpleType:<restriction
624 : base = QName
625 : id = ID
626 : {any attributes with non-schema namespace . . .}>
627 : Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?)
628 : </restriction>
629 : simpleContent:<restriction
630 : base = QName
631 : id = ID
632 : {any attributes with non-schema namespace . . .}>
633 : Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))
634 : </restriction>
635 : */
636 : static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType)
637 350 : {
638 : xmlNodePtr trav;
639 : xmlAttrPtr base;
640 :
641 350 : base = get_attribute(restType->properties, "base");
642 350 : if (base != NULL) {
643 : char *type, *ns;
644 : xmlNsPtr nsptr;
645 :
646 342 : parse_namespace(base->children->content, &type, &ns);
647 342 : nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
648 342 : if (nsptr != NULL) {
649 342 : cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
650 : }
651 342 : if (type) {efree(type);}
652 342 : if (ns) {efree(ns);}
653 8 : } else if (!simpleType) {
654 0 : soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
655 : }
656 :
657 350 : if (cur_type->restrictions == NULL) {
658 350 : cur_type->restrictions = emalloc(sizeof(sdlRestrictions));
659 350 : memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
660 : }
661 :
662 350 : trav = restType->children;
663 350 : if (trav != NULL && node_is_equal(trav, "annotation")) {
664 : /* TODO: <annotation> support */
665 0 : trav = trav->next;
666 : }
667 350 : if (trav != NULL && node_is_equal(trav, "simpleType")) {
668 8 : schema_simpleType(sdl, tns, trav, cur_type);
669 8 : trav = trav->next;
670 : }
671 1608 : while (trav != NULL) {
672 914 : if (node_is_equal(trav, "minExclusive")) {
673 0 : schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
674 914 : } else if (node_is_equal(trav, "minInclusive")) {
675 3 : schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
676 911 : } else if (node_is_equal(trav, "maxExclusive")) {
677 1 : schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
678 910 : } else if (node_is_equal(trav, "maxInclusive")) {
679 1 : schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
680 909 : } else if (node_is_equal(trav, "totalDigits")) {
681 0 : schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
682 909 : } else if (node_is_equal(trav, "fractionDigits")) {
683 0 : schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
684 909 : } else if (node_is_equal(trav, "length")) {
685 0 : schema_restriction_var_int(trav, &cur_type->restrictions->length);
686 909 : } else if (node_is_equal(trav, "minLength")) {
687 0 : schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
688 909 : } else if (node_is_equal(trav, "maxLength")) {
689 0 : schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
690 909 : } else if (node_is_equal(trav, "whiteSpace")) {
691 0 : schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
692 909 : } else if (node_is_equal(trav, "pattern")) {
693 5 : schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
694 904 : } else if (node_is_equal(trav, "enumeration")) {
695 898 : sdlRestrictionCharPtr enumval = NULL;
696 :
697 898 : schema_restriction_var_char(trav, &enumval);
698 898 : if (cur_type->restrictions->enumeration == NULL) {
699 281 : cur_type->restrictions->enumeration = emalloc(sizeof(HashTable));
700 281 : zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0);
701 : }
702 898 : if (zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL) == FAILURE) {
703 0 : delete_restriction_var_char(&enumval);
704 : }
705 : } else {
706 6 : break;
707 : }
708 908 : trav = trav->next;
709 : }
710 350 : if (!simpleType) {
711 18 : while (trav != NULL) {
712 6 : if (node_is_equal(trav,"attribute")) {
713 6 : schema_attribute(sdl, tns, trav, cur_type, NULL);
714 0 : } else if (node_is_equal(trav,"attributeGroup")) {
715 0 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
716 0 : } else if (node_is_equal(trav,"anyAttribute")) {
717 : /* TODO: <anyAttribute> support */
718 0 : trav = trav->next;
719 0 : break;
720 : } else {
721 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
722 : }
723 6 : trav = trav->next;
724 : }
725 : }
726 350 : if (trav != NULL) {
727 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
728 : }
729 :
730 350 : return TRUE;
731 : }
732 :
733 : /*
734 : <restriction
735 : base = QName
736 : id = ID
737 : {any attributes with non-schema namespace . . .}>
738 : Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
739 : </restriction>
740 : */
741 : static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type)
742 939 : {
743 : xmlAttrPtr base;
744 : xmlNodePtr trav;
745 :
746 939 : base = get_attribute(restType->properties, "base");
747 939 : if (base != NULL) {
748 : char *type, *ns;
749 : xmlNsPtr nsptr;
750 :
751 939 : parse_namespace(base->children->content, &type, &ns);
752 939 : nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
753 939 : if (nsptr != NULL) {
754 938 : cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
755 : }
756 939 : if (type) {efree(type);}
757 939 : if (ns) {efree(ns);}
758 : } else {
759 0 : soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
760 : }
761 :
762 939 : trav = restType->children;
763 939 : if (trav != NULL && node_is_equal(trav,"annotation")) {
764 : /* TODO: <annotation> support */
765 0 : trav = trav->next;
766 : }
767 939 : if (trav != NULL) {
768 939 : if (node_is_equal(trav,"group")) {
769 0 : schema_group(sdl, tns, trav, cur_type, NULL);
770 0 : trav = trav->next;
771 939 : } else if (node_is_equal(trav,"all")) {
772 16 : schema_all(sdl, tns, trav, cur_type, NULL);
773 16 : trav = trav->next;
774 923 : } else if (node_is_equal(trav,"choice")) {
775 0 : schema_choice(sdl, tns, trav, cur_type, NULL);
776 0 : trav = trav->next;
777 923 : } else if (node_is_equal(trav,"sequence")) {
778 3 : schema_sequence(sdl, tns, trav, cur_type, NULL);
779 3 : trav = trav->next;
780 : }
781 : }
782 2813 : while (trav != NULL) {
783 935 : if (node_is_equal(trav,"attribute")) {
784 935 : schema_attribute(sdl, tns, trav, cur_type, NULL);
785 0 : } else if (node_is_equal(trav,"attributeGroup")) {
786 0 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
787 0 : } else if (node_is_equal(trav,"anyAttribute")) {
788 : /* TODO: <anyAttribute> support */
789 0 : trav = trav->next;
790 0 : break;
791 : } else {
792 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
793 : }
794 935 : trav = trav->next;
795 : }
796 939 : if (trav != NULL) {
797 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
798 : }
799 :
800 939 : return TRUE;
801 : }
802 :
803 : static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr)
804 5 : {
805 : xmlAttrPtr fixed, value;
806 :
807 5 : if ((*valptr) == NULL) {
808 5 : (*valptr) = emalloc(sizeof(sdlRestrictionInt));
809 : }
810 5 : memset((*valptr), 0, sizeof(sdlRestrictionInt));
811 :
812 5 : fixed = get_attribute(val->properties, "fixed");
813 5 : (*valptr)->fixed = FALSE;
814 5 : if (fixed != NULL) {
815 0 : if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
816 : !strncmp((char*)fixed->children->content, "1", sizeof("1")))
817 0 : (*valptr)->fixed = TRUE;
818 : }
819 :
820 5 : value = get_attribute(val->properties, "value");
821 5 : if (value == NULL) {
822 0 : soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
823 : }
824 :
825 5 : (*valptr)->value = atoi((char*)value->children->content);
826 :
827 5 : return TRUE;
828 : }
829 :
830 : static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr)
831 903 : {
832 : xmlAttrPtr fixed, value;
833 :
834 903 : if ((*valptr) == NULL) {
835 903 : (*valptr) = emalloc(sizeof(sdlRestrictionChar));
836 : }
837 903 : memset((*valptr), 0, sizeof(sdlRestrictionChar));
838 :
839 903 : fixed = get_attribute(val->properties, "fixed");
840 903 : (*valptr)->fixed = FALSE;
841 903 : if (fixed != NULL) {
842 0 : if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
843 : !strncmp((char*)fixed->children->content, "1", sizeof("1"))) {
844 0 : (*valptr)->fixed = TRUE;
845 : }
846 : }
847 :
848 903 : value = get_attribute(val->properties, "value");
849 903 : if (value == NULL) {
850 0 : soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
851 : }
852 :
853 903 : (*valptr)->value = estrdup((char*)value->children->content);
854 903 : return TRUE;
855 : }
856 :
857 : /*
858 : From simpleContent (not supported):
859 : <extension
860 : base = QName
861 : id = ID
862 : {any attributes with non-schema namespace . . .}>
863 : Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
864 : </extension>
865 : */
866 : static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
867 18 : {
868 : xmlNodePtr trav;
869 : xmlAttrPtr base;
870 :
871 18 : base = get_attribute(extType->properties, "base");
872 18 : if (base != NULL) {
873 : char *type, *ns;
874 : xmlNsPtr nsptr;
875 :
876 18 : parse_namespace(base->children->content, &type, &ns);
877 18 : nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
878 18 : if (nsptr != NULL) {
879 18 : cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
880 : }
881 18 : if (type) {efree(type);}
882 18 : if (ns) {efree(ns);}
883 : } else {
884 0 : soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
885 : }
886 :
887 18 : trav = extType->children;
888 18 : if (trav != NULL && node_is_equal(trav,"annotation")) {
889 : /* TODO: <annotation> support */
890 0 : trav = trav->next;
891 : }
892 54 : while (trav != NULL) {
893 18 : if (node_is_equal(trav,"attribute")) {
894 18 : schema_attribute(sdl, tns, trav, cur_type, NULL);
895 0 : } else if (node_is_equal(trav,"attributeGroup")) {
896 0 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
897 0 : } else if (node_is_equal(trav,"anyAttribute")) {
898 : /* TODO: <anyAttribute> support */
899 0 : trav = trav->next;
900 0 : break;
901 : } else {
902 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
903 : }
904 18 : trav = trav->next;
905 : }
906 18 : if (trav != NULL) {
907 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
908 : }
909 18 : return TRUE;
910 : }
911 :
912 : /*
913 : From complexContent:
914 : <extension
915 : base = QName
916 : id = ID
917 : {any attributes with non-schema namespace . . .}>
918 : Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
919 : </extension>
920 : */
921 : static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
922 248 : {
923 : xmlNodePtr trav;
924 : xmlAttrPtr base;
925 :
926 248 : base = get_attribute(extType->properties, "base");
927 248 : if (base != NULL) {
928 : char *type, *ns;
929 : xmlNsPtr nsptr;
930 :
931 248 : parse_namespace(base->children->content, &type, &ns);
932 248 : nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
933 248 : if (nsptr != NULL) {
934 248 : cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
935 : }
936 248 : if (type) {efree(type);}
937 248 : if (ns) {efree(ns);}
938 : } else {
939 0 : soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
940 : }
941 :
942 248 : trav = extType->children;
943 248 : if (trav != NULL && node_is_equal(trav,"annotation")) {
944 : /* TODO: <annotation> support */
945 0 : trav = trav->next;
946 : }
947 248 : if (trav != NULL) {
948 227 : if (node_is_equal(trav,"group")) {
949 0 : schema_group(sdl, tns, trav, cur_type, NULL);
950 0 : trav = trav->next;
951 227 : } else if (node_is_equal(trav,"all")) {
952 4 : schema_all(sdl, tns, trav, cur_type, NULL);
953 4 : trav = trav->next;
954 223 : } else if (node_is_equal(trav,"choice")) {
955 0 : schema_choice(sdl, tns, trav, cur_type, NULL);
956 0 : trav = trav->next;
957 223 : } else if (node_is_equal(trav,"sequence")) {
958 177 : schema_sequence(sdl, tns, trav, cur_type, NULL);
959 177 : trav = trav->next;
960 : }
961 : }
962 782 : while (trav != NULL) {
963 286 : if (node_is_equal(trav,"attribute")) {
964 286 : schema_attribute(sdl, tns, trav, cur_type, NULL);
965 0 : } else if (node_is_equal(trav,"attributeGroup")) {
966 0 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
967 0 : } else if (node_is_equal(trav,"anyAttribute")) {
968 : /* TODO: <anyAttribute> support */
969 0 : trav = trav->next;
970 0 : break;
971 : } else {
972 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
973 : }
974 286 : trav = trav->next;
975 : }
976 248 : if (trav != NULL) {
977 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
978 : }
979 248 : return TRUE;
980 : }
981 :
982 : void schema_min_max(xmlNodePtr node, sdlContentModelPtr model)
983 14515 : {
984 14515 : xmlAttrPtr attr = get_attribute(node->properties, "minOccurs");
985 :
986 14515 : if (attr) {
987 5980 : model->min_occurs = atoi((char*)attr->children->content);
988 : } else {
989 8535 : model->min_occurs = 1;
990 : }
991 :
992 14515 : attr = get_attribute(node->properties, "maxOccurs");
993 14515 : if (attr) {
994 5975 : if (!strncmp((char*)attr->children->content, "unbounded", sizeof("unbounded"))) {
995 982 : model->max_occurs = -1;
996 : } else {
997 4993 : model->max_occurs = atoi((char*)attr->children->content);
998 : }
999 : } else {
1000 8540 : model->max_occurs = 1;
1001 : }
1002 14515 : }
1003 :
1004 : /*
1005 : <all
1006 : id = ID
1007 : maxOccurs = 1 : 1
1008 : minOccurs = (0 | 1) : 1
1009 : {any attributes with non-schema namespace . . .}>
1010 : Content: (annotation?, element*)
1011 : </all>
1012 : */
1013 : static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur_type, sdlContentModelPtr model)
1014 464 : {
1015 : xmlNodePtr trav;
1016 : sdlContentModelPtr newModel;
1017 :
1018 464 : newModel = emalloc(sizeof(sdlContentModel));
1019 464 : newModel->kind = XSD_CONTENT_ALL;
1020 464 : newModel->u.content = emalloc(sizeof(HashTable));
1021 464 : zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1022 464 : if (model == NULL) {
1023 464 : cur_type->model = newModel;
1024 : } else {
1025 0 : zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
1026 : }
1027 :
1028 464 : schema_min_max(all, newModel);
1029 :
1030 464 : trav = all->children;
1031 464 : if (trav != NULL && node_is_equal(trav,"annotation")) {
1032 : /* TODO: <annotation> support */
1033 0 : trav = trav->next;
1034 : }
1035 2432 : while (trav != NULL) {
1036 1504 : if (node_is_equal(trav,"element")) {
1037 1504 : schema_element(sdl, tns, trav, cur_type, newModel);
1038 : } else {
1039 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in all", trav->name);
1040 : }
1041 1504 : trav = trav->next;
1042 : }
1043 464 : return TRUE;
1044 : }
1045 :
1046 : /*
1047 : <group
1048 : name = NCName
1049 : Content: (annotation?, (all | choice | sequence))
1050 : </group>
1051 : <group
1052 : name = NCName
1053 : ref = QName>
1054 : Content: (annotation?)
1055 : </group>
1056 : */
1057 : static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model)
1058 4 : {
1059 : xmlNodePtr trav;
1060 4 : xmlAttrPtr ns, name, ref = NULL;
1061 : sdlContentModelPtr newModel;
1062 :
1063 4 : ns = get_attribute(groupType->properties, "targetNamespace");
1064 4 : if (ns == NULL) {
1065 4 : ns = tns;
1066 : }
1067 :
1068 4 : name = get_attribute(groupType->properties, "name");
1069 4 : if (name == NULL) {
1070 2 : name = ref = get_attribute(groupType->properties, "ref");
1071 : }
1072 :
1073 4 : if (name) {
1074 4 : smart_str key = {0};
1075 :
1076 4 : if (ref) {
1077 : char *type, *ns;
1078 : xmlNsPtr nsptr;
1079 :
1080 2 : parse_namespace(ref->children->content, &type, &ns);
1081 2 : nsptr = xmlSearchNs(groupType->doc, groupType, BAD_CAST(ns));
1082 2 : if (nsptr != NULL) {
1083 2 : smart_str_appends(&key, (char*)nsptr->href);
1084 2 : smart_str_appendc(&key, ':');
1085 : }
1086 2 : smart_str_appends(&key, type);
1087 2 : smart_str_0(&key);
1088 :
1089 2 : newModel = emalloc(sizeof(sdlContentModel));
1090 2 : newModel->kind = XSD_CONTENT_GROUP_REF;
1091 2 : newModel->u.group_ref = estrdup(key.c);
1092 :
1093 2 : if (type) {efree(type);}
1094 2 : if (ns) {efree(ns);}
1095 : } else {
1096 2 : newModel = emalloc(sizeof(sdlContentModel));
1097 2 : newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
1098 2 : newModel->u.content = emalloc(sizeof(HashTable));
1099 2 : zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1100 :
1101 2 : smart_str_appends(&key, (char*)ns->children->content);
1102 2 : smart_str_appendc(&key, ':');
1103 2 : smart_str_appends(&key, (char*)name->children->content);
1104 2 : smart_str_0(&key);
1105 : }
1106 :
1107 4 : if (cur_type == NULL) {
1108 : sdlTypePtr newType;
1109 :
1110 2 : newType = emalloc(sizeof(sdlType));
1111 2 : memset(newType, 0, sizeof(sdlType));
1112 :
1113 2 : if (sdl->groups == NULL) {
1114 2 : sdl->groups = emalloc(sizeof(HashTable));
1115 2 : zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
1116 : }
1117 2 : if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1118 0 : soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
1119 : }
1120 :
1121 2 : cur_type = newType;
1122 : }
1123 4 : smart_str_free(&key);
1124 :
1125 4 : if (model == NULL) {
1126 4 : cur_type->model = newModel;
1127 : } else {
1128 0 : zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1129 : }
1130 : } else {
1131 0 : soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
1132 : }
1133 :
1134 4 : schema_min_max(groupType, newModel);
1135 :
1136 4 : trav = groupType->children;
1137 4 : if (trav != NULL && node_is_equal(trav,"annotation")) {
1138 : /* TODO: <annotation> support */
1139 0 : trav = trav->next;
1140 : }
1141 4 : if (trav != NULL) {
1142 2 : if (node_is_equal(trav,"choice")) {
1143 0 : if (ref != NULL) {
1144 0 : soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1145 : }
1146 0 : newModel->kind = XSD_CONTENT_CHOICE;
1147 0 : schema_choice(sdl, tns, trav, cur_type, newModel);
1148 0 : trav = trav->next;
1149 2 : } else if (node_is_equal(trav,"sequence")) {
1150 2 : if (ref != NULL) {
1151 0 : soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1152 : }
1153 2 : newModel->kind = XSD_CONTENT_SEQUENCE;
1154 2 : schema_sequence(sdl, tns, trav, cur_type, newModel);
1155 2 : trav = trav->next;
1156 0 : } else if (node_is_equal(trav,"all")) {
1157 0 : if (ref != NULL) {
1158 0 : soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1159 : }
1160 0 : newModel->kind = XSD_CONTENT_ALL;
1161 0 : schema_all(sdl, tns, trav, cur_type, newModel);
1162 0 : trav = trav->next;
1163 : } else {
1164 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
1165 : }
1166 : }
1167 4 : if (trav != NULL) {
1168 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
1169 : }
1170 4 : return TRUE;
1171 : }
1172 : /*
1173 : <choice
1174 : id = ID
1175 : maxOccurs = (nonNegativeInteger | unbounded) : 1
1176 : minOccurs = nonNegativeInteger : 1
1177 : {any attributes with non-schema namespace . . .}>
1178 : Content: (annotation?, (element | group | choice | sequence | any)*)
1179 : </choice>
1180 : */
1181 : static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
1182 92 : {
1183 : xmlNodePtr trav;
1184 : sdlContentModelPtr newModel;
1185 :
1186 92 : newModel = emalloc(sizeof(sdlContentModel));
1187 92 : newModel->kind = XSD_CONTENT_CHOICE;
1188 92 : newModel->u.content = emalloc(sizeof(HashTable));
1189 92 : zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1190 92 : if (model == NULL) {
1191 2 : cur_type->model = newModel;
1192 : } else {
1193 90 : zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
1194 : }
1195 :
1196 92 : schema_min_max(choiceType, newModel);
1197 :
1198 92 : trav = choiceType->children;
1199 92 : if (trav != NULL && node_is_equal(trav,"annotation")) {
1200 : /* TODO: <annotation> support */
1201 0 : trav = trav->next;
1202 : }
1203 452 : while (trav != NULL) {
1204 268 : if (node_is_equal(trav,"element")) {
1205 268 : schema_element(sdl, tns, trav, cur_type, newModel);
1206 0 : } else if (node_is_equal(trav,"group")) {
1207 0 : schema_group(sdl, tns, trav, cur_type, newModel);
1208 0 : } else if (node_is_equal(trav,"choice")) {
1209 0 : schema_choice(sdl, tns, trav, cur_type, newModel);
1210 0 : } else if (node_is_equal(trav,"sequence")) {
1211 0 : schema_sequence(sdl, tns, trav, cur_type, newModel);
1212 0 : } else if (node_is_equal(trav,"any")) {
1213 0 : schema_any(sdl, tns, trav, cur_type, newModel);
1214 : } else {
1215 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name);
1216 : }
1217 268 : trav = trav->next;
1218 : }
1219 92 : return TRUE;
1220 : }
1221 :
1222 : /*
1223 : <sequence
1224 : id = ID
1225 : maxOccurs = (nonNegativeInteger | unbounded) : 1
1226 : minOccurs = nonNegativeInteger : 1
1227 : {any attributes with non-schema namespace . . .}>
1228 : Content: (annotation?, (element | group | choice | sequence | any)*)
1229 : </sequence>
1230 : */
1231 : static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
1232 5162 : {
1233 : xmlNodePtr trav;
1234 : sdlContentModelPtr newModel;
1235 :
1236 5162 : newModel = emalloc(sizeof(sdlContentModel));
1237 5162 : newModel->kind = XSD_CONTENT_SEQUENCE;
1238 5162 : newModel->u.content = emalloc(sizeof(HashTable));
1239 5162 : zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1240 5162 : if (model == NULL) {
1241 5160 : cur_type->model = newModel;
1242 : } else {
1243 2 : zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
1244 : }
1245 :
1246 5162 : schema_min_max(seqType, newModel);
1247 :
1248 5162 : trav = seqType->children;
1249 5162 : if (trav != NULL && node_is_equal(trav,"annotation")) {
1250 : /* TODO: <annotation> support */
1251 1 : trav = trav->next;
1252 : }
1253 17435 : while (trav != NULL) {
1254 7111 : if (node_is_equal(trav,"element")) {
1255 6874 : schema_element(sdl, tns, trav, cur_type, newModel);
1256 237 : } else if (node_is_equal(trav,"group")) {
1257 0 : schema_group(sdl, tns, trav, cur_type, newModel);
1258 237 : } else if (node_is_equal(trav,"choice")) {
1259 90 : schema_choice(sdl, tns, trav, cur_type, newModel);
1260 147 : } else if (node_is_equal(trav,"sequence")) {
1261 0 : schema_sequence(sdl, tns, trav, cur_type, newModel);
1262 147 : } else if (node_is_equal(trav,"any")) {
1263 147 : schema_any(sdl, tns, trav, cur_type, newModel);
1264 : } else {
1265 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name);
1266 : }
1267 7111 : trav = trav->next;
1268 : }
1269 5162 : return TRUE;
1270 : }
1271 :
1272 : /*
1273 : <any
1274 : id = ID
1275 : maxOccurs = (nonNegativeInteger | unbounded) : 1
1276 : minOccurs = nonNegativeInteger : 1
1277 : namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
1278 : processContents = (lax | skip | strict) : strict
1279 : {any attributes with non-schema namespace . . .}>
1280 : Content: (annotation?)
1281 : </any>
1282 : */
1283 : static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
1284 147 : {
1285 147 : if (model != NULL) {
1286 : sdlContentModelPtr newModel;
1287 :
1288 147 : newModel = emalloc(sizeof(sdlContentModel));
1289 147 : newModel->kind = XSD_CONTENT_ANY;
1290 :
1291 147 : schema_min_max(anyType, newModel);
1292 :
1293 147 : zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1294 : }
1295 147 : return TRUE;
1296 : }
1297 :
1298 : /*
1299 : <complexContent
1300 : id = ID
1301 : mixed = boolean
1302 : {any attributes with non-schema namespace . . .}>
1303 : Content: (annotation?, (restriction | extension))
1304 : </complexContent>
1305 : */
1306 : static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
1307 1187 : {
1308 : xmlNodePtr trav;
1309 :
1310 1187 : trav = compCont->children;
1311 1187 : if (trav != NULL && node_is_equal(trav,"annotation")) {
1312 : /* TODO: <annotation> support */
1313 0 : trav = trav->next;
1314 : }
1315 1187 : if (trav != NULL) {
1316 1187 : if (node_is_equal(trav, "restriction")) {
1317 939 : cur_type->kind = XSD_TYPEKIND_RESTRICTION;
1318 939 : schema_restriction_complexContent(sdl, tns, trav, cur_type);
1319 939 : trav = trav->next;
1320 248 : } else if (node_is_equal(trav, "extension")) {
1321 248 : cur_type->kind = XSD_TYPEKIND_EXTENSION;
1322 248 : schema_extension_complexContent(sdl, tns, trav, cur_type);
1323 248 : trav = trav->next;
1324 : } else {
1325 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
1326 : }
1327 : } else {
1328 0 : soap_error0(E_ERROR, "Parsing Schema: <restriction> or <extension> expected in complexContent");
1329 : }
1330 1187 : if (trav != NULL) {
1331 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
1332 : }
1333 :
1334 1187 : return TRUE;
1335 : }
1336 :
1337 : /*
1338 : <complexType
1339 : abstract = boolean : false
1340 : block = (#all | List of (extension | restriction))
1341 : final = (#all | List of (extension | restriction))
1342 : id = ID
1343 : mixed = boolean : false
1344 : name = NCName
1345 : {any attributes with non-schema namespace . . .}>
1346 : Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1347 : </complexType>
1348 : */
1349 : static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
1350 7571 : {
1351 : xmlNodePtr trav;
1352 : xmlAttrPtr attrs, name, ns;
1353 :
1354 7571 : attrs = compType->properties;
1355 7571 : ns = get_attribute(attrs, "targetNamespace");
1356 7571 : if (ns == NULL) {
1357 7571 : ns = tns;
1358 : }
1359 :
1360 7571 : name = get_attribute(attrs, "name");
1361 7571 : if (cur_type != NULL) {
1362 : /* Anonymous type inside <element> */
1363 : sdlTypePtr newType, *ptr;
1364 :
1365 4185 : newType = emalloc(sizeof(sdlType));
1366 4185 : memset(newType, 0, sizeof(sdlType));
1367 4185 : newType->kind = XSD_TYPEKIND_COMPLEX;
1368 4185 : if (name != NULL) {
1369 2 : newType->name = estrdup((char*)name->children->content);
1370 2 : newType->namens = estrdup((char*)ns->children->content);
1371 : } else {
1372 4183 : newType->name = estrdup(cur_type->name);
1373 4183 : newType->namens = estrdup(cur_type->namens);
1374 : }
1375 :
1376 4185 : zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
1377 :
1378 4185 : if (sdl->encoders == NULL) {
1379 85 : sdl->encoders = emalloc(sizeof(HashTable));
1380 85 : zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
1381 : }
1382 4185 : cur_type->encode = emalloc(sizeof(encode));
1383 4185 : memset(cur_type->encode, 0, sizeof(encode));
1384 4185 : cur_type->encode->details.ns = estrdup(newType->namens);
1385 4185 : cur_type->encode->details.type_str = estrdup(newType->name);
1386 4185 : cur_type->encode->details.sdl_type = *ptr;
1387 4185 : cur_type->encode->to_xml = sdl_guess_convert_xml;
1388 4185 : cur_type->encode->to_zval = sdl_guess_convert_zval;
1389 4185 : zend_hash_next_index_insert(sdl->encoders, &cur_type->encode, sizeof(encodePtr), NULL);
1390 :
1391 4185 : cur_type =*ptr;
1392 :
1393 3386 : } else if (name) {
1394 : sdlTypePtr newType, *ptr;
1395 :
1396 3386 : newType = emalloc(sizeof(sdlType));
1397 3386 : memset(newType, 0, sizeof(sdlType));
1398 3386 : newType->kind = XSD_TYPEKIND_COMPLEX;
1399 3386 : newType->name = estrdup((char*)name->children->content);
1400 3386 : newType->namens = estrdup((char*)ns->children->content);
1401 :
1402 3386 : zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
1403 :
1404 3386 : cur_type = (*ptr);
1405 3386 : create_encoder(sdl, cur_type, ns->children->content, name->children->content);
1406 : } else {
1407 0 : soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
1408 0 : return FALSE;
1409 : }
1410 :
1411 7571 : trav = compType->children;
1412 7571 : if (trav != NULL && node_is_equal(trav, "annotation")) {
1413 : /* TODO: <annotation> support */
1414 3 : trav = trav->next;
1415 : }
1416 7571 : if (trav != NULL) {
1417 6820 : if (node_is_equal(trav,"simpleContent")) {
1418 24 : schema_simpleContent(sdl, tns, trav, cur_type);
1419 24 : trav = trav->next;
1420 6796 : } else if (node_is_equal(trav,"complexContent")) {
1421 1187 : schema_complexContent(sdl, tns, trav, cur_type);
1422 1187 : trav = trav->next;
1423 : } else {
1424 5609 : if (node_is_equal(trav,"group")) {
1425 2 : schema_group(sdl, tns, trav, cur_type, NULL);
1426 2 : trav = trav->next;
1427 5607 : } else if (node_is_equal(trav,"all")) {
1428 444 : schema_all(sdl, tns, trav, cur_type, NULL);
1429 444 : trav = trav->next;
1430 5163 : } else if (node_is_equal(trav,"choice")) {
1431 2 : schema_choice(sdl, tns, trav, cur_type, NULL);
1432 2 : trav = trav->next;
1433 5161 : } else if (node_is_equal(trav,"sequence")) {
1434 4980 : schema_sequence(sdl, tns, trav, cur_type, NULL);
1435 4980 : trav = trav->next;
1436 : }
1437 11686 : while (trav != NULL) {
1438 476 : if (node_is_equal(trav,"attribute")) {
1439 464 : schema_attribute(sdl, tns, trav, cur_type, NULL);
1440 12 : } else if (node_is_equal(trav,"attributeGroup")) {
1441 4 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
1442 8 : } else if (node_is_equal(trav,"anyAttribute")) {
1443 : /* TODO: <anyAttribute> support */
1444 8 : trav = trav->next;
1445 8 : break;
1446 : } else {
1447 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
1448 : }
1449 468 : trav = trav->next;
1450 : }
1451 : }
1452 : }
1453 7571 : if (trav != NULL) {
1454 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
1455 : }
1456 7571 : return TRUE;
1457 : }
1458 : /*
1459 : <element
1460 : abstract = boolean : false
1461 : block = (#all | List of (extension | restriction | substitution))
1462 : default = string
1463 : final = (#all | List of (extension | restriction))
1464 : fixed = string
1465 : form = (qualified | unqualified)
1466 : id = ID
1467 : maxOccurs = (nonNegativeInteger | unbounded) : 1
1468 : minOccurs = nonNegativeInteger : 1
1469 : name = NCName
1470 : nillable = boolean : false
1471 : ref = QName
1472 : substitutionGroup = QName
1473 : type = QName
1474 : {any attributes with non-schema namespace . . .}>
1475 : Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
1476 : </element>
1477 : */
1478 : static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
1479 15056 : {
1480 : xmlNodePtr trav;
1481 15056 : xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
1482 :
1483 15056 : attrs = element->properties;
1484 15056 : ns = get_attribute(attrs, "targetNamespace");
1485 15056 : if (ns == NULL) {
1486 15056 : ns = tns;
1487 : }
1488 :
1489 15056 : name = get_attribute(attrs, "name");
1490 15056 : if (name == NULL) {
1491 160 : name = ref = get_attribute(attrs, "ref");
1492 : }
1493 :
1494 15056 : if (name) {
1495 : HashTable *addHash;
1496 : sdlTypePtr newType;
1497 15056 : smart_str key = {0};
1498 :
1499 15056 : newType = emalloc(sizeof(sdlType));
1500 15056 : memset(newType, 0, sizeof(sdlType));
1501 :
1502 15056 : if (ref) {
1503 160 : smart_str nscat = {0};
1504 : char *type, *ns;
1505 : xmlNsPtr nsptr;
1506 :
1507 160 : parse_namespace(ref->children->content, &type, &ns);
1508 160 : nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
1509 160 : if (nsptr != NULL) {
1510 160 : smart_str_appends(&nscat, (char*)nsptr->href);
1511 160 : smart_str_appendc(&nscat, ':');
1512 160 : newType->namens = estrdup((char*)nsptr->href);
1513 : }
1514 160 : smart_str_appends(&nscat, type);
1515 160 : newType->name = estrdup(type);
1516 160 : smart_str_0(&nscat);
1517 160 : if (type) {efree(type);}
1518 160 : if (ns) {efree(ns);}
1519 160 : newType->ref = estrdup(nscat.c);
1520 160 : smart_str_free(&nscat);
1521 : } else {
1522 14896 : newType->name = estrdup((char*)name->children->content);
1523 14896 : newType->namens = estrdup((char*)ns->children->content);
1524 : }
1525 :
1526 15056 : newType->nillable = FALSE;
1527 :
1528 15056 : if (cur_type == NULL) {
1529 6410 : if (sdl->elements == NULL) {
1530 274 : sdl->elements = emalloc(sizeof(HashTable));
1531 274 : zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
1532 : }
1533 6410 : addHash = sdl->elements;
1534 6410 : smart_str_appends(&key, newType->namens);
1535 6410 : smart_str_appendc(&key, ':');
1536 6410 : smart_str_appends(&key, newType->name);
1537 : } else {
1538 8646 : if (cur_type->elements == NULL) {
1539 5484 : cur_type->elements = emalloc(sizeof(HashTable));
1540 5484 : zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
1541 : }
1542 8646 : addHash = cur_type->elements;
1543 8646 : smart_str_appends(&key, newType->name);
1544 : }
1545 :
1546 15056 : smart_str_0(&key);
1547 15056 : if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1548 0 : if (cur_type == NULL) {
1549 0 : soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
1550 : } else {
1551 0 : zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
1552 : }
1553 : }
1554 15056 : smart_str_free(&key);
1555 :
1556 15056 : if (model != NULL) {
1557 8646 : sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
1558 :
1559 8646 : newModel->kind = XSD_CONTENT_ELEMENT;
1560 8646 : newModel->u.element = newType;
1561 :
1562 8646 : schema_min_max(element, newModel);
1563 :
1564 :
1565 8646 : zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1566 : }
1567 15056 : cur_type = newType;
1568 : } else {
1569 0 : soap_error0(E_ERROR, "Parsing Schema: element has no 'name' nor 'ref' attributes");
1570 : }
1571 :
1572 : /* nillable = boolean : false */
1573 15056 : attrs = element->properties;
1574 15056 : attr = get_attribute(attrs, "nillable");
1575 15056 : if (attr) {
1576 441 : if (ref != NULL) {
1577 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
1578 : }
1579 882 : if (!stricmp((char*)attr->children->content, "true") ||
1580 : !stricmp((char*)attr->children->content, "1")) {
1581 441 : cur_type->nillable = TRUE;
1582 : } else {
1583 0 : cur_type->nillable = FALSE;
1584 : }
1585 : } else {
1586 14615 : cur_type->nillable = FALSE;
1587 : }
1588 :
1589 15056 : attr = get_attribute(attrs, "fixed");
1590 15056 : if (attr) {
1591 0 : if (ref != NULL) {
1592 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
1593 : }
1594 0 : cur_type->fixed = estrdup((char*)attr->children->content);
1595 : }
1596 :
1597 15056 : attr = get_attribute(attrs, "default");
1598 15056 : if (attr) {
1599 3 : if (ref != NULL) {
1600 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
1601 3 : } else if (ref != NULL) {
1602 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
1603 : }
1604 3 : cur_type->def = estrdup((char*)attr->children->content);
1605 : }
1606 :
1607 : /* form */
1608 15056 : attr = get_attribute(attrs, "form");
1609 15056 : if (attr) {
1610 12 : if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
1611 6 : cur_type->form = XSD_FORM_QUALIFIED;
1612 6 : } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
1613 6 : cur_type->form = XSD_FORM_UNQUALIFIED;
1614 : } else {
1615 0 : cur_type->form = XSD_FORM_DEFAULT;
1616 : }
1617 : } else {
1618 15044 : cur_type->form = XSD_FORM_DEFAULT;
1619 : }
1620 15056 : if (cur_type->form == XSD_FORM_DEFAULT) {
1621 15044 : xmlNodePtr parent = element->parent;
1622 52549 : while (parent) {
1623 37505 : if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
1624 : xmlAttrPtr def;
1625 15044 : def = get_attribute(parent->properties, "elementFormDefault");
1626 16816 : if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
1627 1772 : cur_type->form = XSD_FORM_UNQUALIFIED;
1628 : } else {
1629 13272 : cur_type->form = XSD_FORM_QUALIFIED;
1630 : }
1631 15044 : break;
1632 : }
1633 22461 : parent = parent->parent;
1634 : }
1635 15044 : if (parent == NULL) {
1636 0 : cur_type->form = XSD_FORM_UNQUALIFIED;
1637 : }
1638 : }
1639 :
1640 : /* type = QName */
1641 15056 : type = get_attribute(attrs, "type");
1642 15056 : if (type) {
1643 : char *cptype, *str_ns;
1644 : xmlNsPtr nsptr;
1645 :
1646 10487 : if (ref != NULL) {
1647 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
1648 : }
1649 10487 : parse_namespace(type->children->content, &cptype, &str_ns);
1650 10487 : nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
1651 10487 : if (nsptr != NULL) {
1652 10483 : cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
1653 : }
1654 10487 : if (str_ns) {efree(str_ns);}
1655 10487 : if (cptype) {efree(cptype);}
1656 : }
1657 :
1658 15056 : trav = element->children;
1659 15056 : if (trav != NULL && node_is_equal(trav, "annotation")) {
1660 : /* TODO: <annotation> support */
1661 54 : trav = trav->next;
1662 : }
1663 15056 : if (trav != NULL) {
1664 4188 : if (node_is_equal(trav,"simpleType")) {
1665 3 : if (ref != NULL) {
1666 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
1667 3 : } else if (type != NULL) {
1668 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
1669 : }
1670 3 : schema_simpleType(sdl, tns, trav, cur_type);
1671 3 : trav = trav->next;
1672 4185 : } else if (node_is_equal(trav,"complexType")) {
1673 4185 : if (ref != NULL) {
1674 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
1675 4185 : } else if (type != NULL) {
1676 0 : soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
1677 : }
1678 4185 : schema_complexType(sdl, tns, trav, cur_type);
1679 4185 : trav = trav->next;
1680 : }
1681 : }
1682 30120 : while (trav != NULL) {
1683 8 : if (node_is_equal(trav,"unique")) {
1684 : /* TODO: <unique> support */
1685 7 : } else if (node_is_equal(trav,"key")) {
1686 : /* TODO: <key> support */
1687 6 : } else if (node_is_equal(trav,"keyref")) {
1688 : /* TODO: <keyref> support */
1689 : } else {
1690 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name);
1691 : }
1692 8 : trav = trav->next;
1693 : }
1694 :
1695 15056 : return TRUE;
1696 : }
1697 :
1698 : /*
1699 : <attribute
1700 : default = string
1701 : fixed = string
1702 : form = (qualified | unqualified)
1703 : id = ID
1704 : name = NCName
1705 : ref = QName
1706 : type = QName
1707 : use = (optional | prohibited | required) : optional
1708 : {any attributes with non-schema namespace . . .}>
1709 : Content: (annotation?, (simpleType?))
1710 : </attribute>
1711 : */
1712 : static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
1713 1746 : {
1714 : sdlAttributePtr newAttr;
1715 1746 : xmlAttrPtr attr, name, ref = NULL, type = NULL;
1716 : xmlNodePtr trav;
1717 :
1718 1746 : name = get_attribute(attrType->properties, "name");
1719 1746 : if (name == NULL) {
1720 1099 : name = ref = get_attribute(attrType->properties, "ref");
1721 : }
1722 1746 : if (name) {
1723 : HashTable *addHash;
1724 1746 : smart_str key = {0};
1725 :
1726 1746 : newAttr = emalloc(sizeof(sdlAttribute));
1727 1746 : memset(newAttr, 0, sizeof(sdlAttribute));
1728 :
1729 1746 : if (ref) {
1730 : char *attr_name, *ns;
1731 : xmlNsPtr nsptr;
1732 :
1733 1099 : parse_namespace(ref->children->content, &attr_name, &ns);
1734 1099 : nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
1735 1099 : if (nsptr != NULL) {
1736 1098 : smart_str_appends(&key, (char*)nsptr->href);
1737 1098 : smart_str_appendc(&key, ':');
1738 1098 : newAttr->namens = estrdup((char*)nsptr->href);
1739 : }
1740 1099 : smart_str_appends(&key, attr_name);
1741 1099 : smart_str_0(&key);
1742 1099 : newAttr->ref = estrdup(key.c);
1743 1099 : if (attr_name) {efree(attr_name);}
1744 1099 : if (ns) {efree(ns);}
1745 : } else {
1746 : xmlAttrPtr ns;
1747 :
1748 647 : ns = get_attribute(attrType->properties, "targetNamespace");
1749 647 : if (ns == NULL) {
1750 647 : ns = tns;
1751 : }
1752 647 : if (ns != NULL) {
1753 647 : smart_str_appends(&key, (char*)ns->children->content);
1754 647 : smart_str_appendc(&key, ':');
1755 647 : newAttr->namens = estrdup((char*)ns->children->content);
1756 : }
1757 647 : smart_str_appends(&key, (char*)name->children->content);
1758 647 : smart_str_0(&key);
1759 : }
1760 :
1761 1746 : if (cur_type == NULL) {
1762 18 : addHash = ctx->attributes;
1763 : } else {
1764 1728 : if (cur_type->attributes == NULL) {
1765 1246 : cur_type->attributes = emalloc(sizeof(HashTable));
1766 1246 : zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
1767 : }
1768 1728 : addHash = cur_type->attributes;
1769 : }
1770 :
1771 1746 : if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
1772 0 : soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
1773 : }
1774 1746 : smart_str_free(&key);
1775 : } else{
1776 0 : soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes");
1777 : }
1778 :
1779 : /* type = QName */
1780 1746 : type = get_attribute(attrType->properties, "type");
1781 1746 : if (type) {
1782 : char *cptype, *str_ns;
1783 : xmlNsPtr nsptr;
1784 :
1785 637 : if (ref != NULL) {
1786 0 : soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
1787 : }
1788 637 : parse_namespace(type->children->content, &cptype, &str_ns);
1789 637 : nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
1790 637 : if (nsptr != NULL) {
1791 637 : newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
1792 : }
1793 637 : if (str_ns) {efree(str_ns);}
1794 637 : if (cptype) {efree(cptype);}
1795 : }
1796 :
1797 1746 : attr = attrType->properties;
1798 7095 : while (attr != NULL) {
1799 3603 : if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
1800 38 : newAttr->def = estrdup((char*)attr->children->content);
1801 3565 : } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
1802 7 : newAttr->fixed = estrdup((char*)attr->children->content);
1803 3558 : } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
1804 12 : if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
1805 6 : newAttr->form = XSD_FORM_QUALIFIED;
1806 6 : } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
1807 6 : newAttr->form = XSD_FORM_UNQUALIFIED;
1808 : } else {
1809 0 : newAttr->form = XSD_FORM_DEFAULT;
1810 : }
1811 3546 : } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
1812 : /* skip */
1813 3546 : } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
1814 614 : newAttr->name = estrdup((char*)attr->children->content);
1815 2932 : } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
1816 : /* already processed */
1817 1838 : } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
1818 : /* already processed */
1819 1232 : } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
1820 191 : if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
1821 0 : newAttr->use = XSD_USE_PROHIBITED;
1822 191 : } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
1823 191 : newAttr->use = XSD_USE_REQUIRED;
1824 0 : } else if (strncmp((char*)attr->children->content, "optional", sizeof("optional")) == 0) {
1825 0 : newAttr->use = XSD_USE_OPTIONAL;
1826 : } else {
1827 0 : newAttr->use = XSD_USE_DEFAULT;
1828 : }
1829 : } else {
1830 1041 : xmlNsPtr nsPtr = attr_find_ns(attr);
1831 :
1832 1041 : if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
1833 1041 : smart_str key2 = {0};
1834 : sdlExtraAttributePtr ext;
1835 : xmlNsPtr nsptr;
1836 : char *value, *ns;
1837 :
1838 1041 : ext = emalloc(sizeof(sdlExtraAttribute));
1839 1041 : memset(ext, 0, sizeof(sdlExtraAttribute));
1840 1041 : parse_namespace(attr->children->content, &value, &ns);
1841 1041 : nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
1842 1041 : if (nsptr) {
1843 1040 : ext->ns = estrdup((char*)nsptr->href);
1844 1040 : ext->val = estrdup(value);
1845 : } else {
1846 1 : ext->val = estrdup((char*)attr->children->content);
1847 : }
1848 1041 : if (ns) {efree(ns);}
1849 1041 : efree(value);
1850 :
1851 1041 : if (!newAttr->extraAttributes) {
1852 970 : newAttr->extraAttributes = emalloc(sizeof(HashTable));
1853 970 : zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
1854 : }
1855 :
1856 1041 : smart_str_appends(&key2, (char*)nsPtr->href);
1857 1041 : smart_str_appendc(&key2, ':');
1858 1041 : smart_str_appends(&key2, (char*)attr->name);
1859 1041 : smart_str_0(&key2);
1860 1041 : zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
1861 1041 : smart_str_free(&key2);
1862 : }
1863 : }
1864 3603 : attr = attr->next;
1865 : }
1866 1746 : if (newAttr->form == XSD_FORM_DEFAULT) {
1867 1734 : xmlNodePtr parent = attrType->parent;
1868 7823 : while (parent) {
1869 6089 : if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
1870 : xmlAttrPtr def;
1871 1734 : def = get_attribute(parent->properties, "attributeFormDefault");
1872 3464 : if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
1873 1730 : newAttr->form = XSD_FORM_UNQUALIFIED;
1874 : } else {
1875 4 : newAttr->form = XSD_FORM_QUALIFIED;
1876 : }
1877 1734 : break;
1878 : }
1879 4355 : parent = parent->parent;
1880 : }
1881 1734 : if (parent == NULL) {
1882 0 : newAttr->form = XSD_FORM_UNQUALIFIED;
1883 : }
1884 : }
1885 1746 : trav = attrType->children;
1886 1746 : if (trav != NULL && node_is_equal(trav, "annotation")) {
1887 : /* TODO: <annotation> support */
1888 41 : trav = trav->next;
1889 : }
1890 1746 : if (trav != NULL) {
1891 10 : if (node_is_equal(trav,"simpleType")) {
1892 : sdlTypePtr dummy_type;
1893 10 : if (ref != NULL) {
1894 0 : soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
1895 10 : } else if (type != NULL) {
1896 0 : soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
1897 : }
1898 10 : dummy_type = emalloc(sizeof(sdlType));
1899 10 : memset(dummy_type, 0, sizeof(sdlType));
1900 : {
1901 10 : smart_str anonymous = {0};
1902 :
1903 10 : smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
1904 10 : smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
1905 10 : smart_str_0(&anonymous);
1906 10 : dummy_type->name = anonymous.c;
1907 : }
1908 10 : dummy_type->namens = estrdup((char*)tns->children->content);
1909 10 : schema_simpleType(sdl, tns, trav, dummy_type);
1910 10 : newAttr->encode = dummy_type->encode;
1911 10 : delete_type(&dummy_type);
1912 10 : trav = trav->next;
1913 : }
1914 : }
1915 1746 : if (trav != NULL) {
1916 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
1917 : }
1918 1746 : return TRUE;
1919 : }
1920 :
1921 : static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
1922 13 : {
1923 : xmlNodePtr trav;
1924 13 : xmlAttrPtr name, ref = NULL;
1925 :
1926 :
1927 13 : name = get_attribute(attrGroup->properties, "name");
1928 13 : if (name == NULL) {
1929 4 : name = ref = get_attribute(attrGroup->properties, "ref");
1930 : }
1931 13 : if (name) {
1932 13 : if (cur_type == NULL) {
1933 : xmlAttrPtr ns;
1934 : sdlTypePtr newType;
1935 9 : smart_str key = {0};
1936 :
1937 9 : ns = get_attribute(attrGroup->properties, "targetNamespace");
1938 9 : if (ns == NULL) {
1939 9 : ns = tns;
1940 : }
1941 9 : newType = emalloc(sizeof(sdlType));
1942 9 : memset(newType, 0, sizeof(sdlType));
1943 9 : newType->name = estrdup((char*)name->children->content);
1944 9 : newType->namens = estrdup((char*)ns->children->content);
1945 :
1946 9 : smart_str_appends(&key, newType->namens);
1947 9 : smart_str_appendc(&key, ':');
1948 9 : smart_str_appends(&key, newType->name);
1949 9 : smart_str_0(&key);
1950 :
1951 9 : if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1952 0 : soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
1953 : }
1954 9 : cur_type = newType;
1955 9 : smart_str_free(&key);
1956 4 : } else if (ref) {
1957 : sdlAttributePtr newAttr;
1958 : char *group_name, *ns;
1959 4 : smart_str key = {0};
1960 : xmlNsPtr nsptr;
1961 :
1962 4 : if (cur_type->attributes == NULL) {
1963 2 : cur_type->attributes = emalloc(sizeof(HashTable));
1964 2 : zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
1965 : }
1966 4 : newAttr = emalloc(sizeof(sdlAttribute));
1967 4 : memset(newAttr, 0, sizeof(sdlAttribute));
1968 :
1969 4 : parse_namespace(ref->children->content, &group_name, &ns);
1970 4 : nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
1971 4 : if (nsptr != NULL) {
1972 4 : smart_str_appends(&key, (char*)nsptr->href);
1973 4 : smart_str_appendc(&key, ':');
1974 : }
1975 4 : smart_str_appends(&key, group_name);
1976 4 : smart_str_0(&key);
1977 4 : newAttr->ref = estrdup(key.c);
1978 4 : if (group_name) {efree(group_name);}
1979 4 : if (ns) {efree(ns);}
1980 4 : smart_str_free(&key);
1981 :
1982 4 : zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
1983 4 : cur_type = NULL;
1984 : }
1985 : } else{
1986 0 : soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
1987 : }
1988 :
1989 13 : trav = attrGroup->children;
1990 13 : if (trav != NULL && node_is_equal(trav, "annotation")) {
1991 : /* TODO: <annotation> support */
1992 1 : trav = trav->next;
1993 : }
1994 45 : while (trav != NULL) {
1995 19 : if (node_is_equal(trav,"attribute")) {
1996 19 : if (ref != NULL) {
1997 0 : soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
1998 : }
1999 19 : schema_attribute(sdl, tns, trav, cur_type, NULL);
2000 0 : } else if (node_is_equal(trav,"attributeGroup")) {
2001 0 : if (ref != NULL) {
2002 0 : soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
2003 : }
2004 0 : schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
2005 0 : } else if (node_is_equal(trav,"anyAttribute")) {
2006 0 : if (ref != NULL) {
2007 0 : soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
2008 : }
2009 : /* TODO: <anyAttribute> support */
2010 0 : trav = trav->next;
2011 0 : break;
2012 : } else {
2013 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
2014 : }
2015 19 : trav = trav->next;
2016 : }
2017 13 : if (trav != NULL) {
2018 0 : soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
2019 : }
2020 13 : return TRUE;
2021 : }
2022 :
2023 : static void copy_extra_attribute(void *attribute)
2024 0 : {
2025 0 : sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
2026 : sdlExtraAttributePtr new_attr;
2027 :
2028 0 : new_attr = emalloc(sizeof(sdlExtraAttribute));
2029 0 : memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
2030 0 : *attr = new_attr;
2031 0 : if (new_attr->ns) {
2032 0 : new_attr->ns = estrdup(new_attr->ns);
2033 : }
2034 0 : if (new_attr->val) {
2035 0 : new_attr->val = estrdup(new_attr->val);
2036 : }
2037 0 : }
2038 :
2039 : static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
2040 1774 : {
2041 : sdlAttributePtr *tmp;
2042 :
2043 1774 : if (attr->ref != NULL) {
2044 1099 : if (ctx->attributes != NULL) {
2045 1099 : if (zend_hash_find(ctx->attributes, attr->ref, strlen(attr->ref)+1, (void**)&tmp) == SUCCESS) {
2046 20 : schema_attribute_fixup(ctx, *tmp);
2047 20 : if ((*tmp)->name != NULL && attr->name == NULL) {
2048 20 : attr->name = estrdup((*tmp)->name);
2049 : }
2050 20 : if ((*tmp)->namens != NULL && attr->namens == NULL) {
2051 0 : attr->namens = estrdup((*tmp)->namens);
2052 : }
2053 20 : if ((*tmp)->def != NULL && attr->def == NULL) {
2054 4 : attr->def = estrdup((*tmp)->def);
2055 : }
2056 20 : if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
2057 0 : attr->fixed = estrdup((*tmp)->fixed);
2058 : }
2059 20 : if (attr->form == XSD_FORM_DEFAULT) {
2060 0 : attr->form = (*tmp)->form;
2061 : }
2062 20 : if (attr->use == XSD_USE_DEFAULT) {
2063 20 : attr->use = (*tmp)->use;
2064 : }
2065 20 : if ((*tmp)->extraAttributes != NULL) {
2066 : xmlNodePtr node;
2067 :
2068 0 : attr->extraAttributes = emalloc(sizeof(HashTable));
2069 0 : zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
2070 0 : zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
2071 : }
2072 20 : attr->encode = (*tmp)->encode;
2073 : }
2074 : }
2075 1099 : if (attr->name == NULL && attr->ref != NULL) {
2076 1079 : char *name = strrchr(attr->ref, ':');
2077 1079 : if (name) {
2078 1078 : attr->name = estrdup(name+1);
2079 : } else{
2080 1 : attr->name = estrdup(attr->ref);
2081 : }
2082 : }
2083 1099 : efree(attr->ref);
2084 1099 : attr->ref = NULL;
2085 : }
2086 1774 : }
2087 :
2088 : static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
2089 4 : {
2090 : sdlTypePtr *tmp;
2091 : sdlAttributePtr *tmp_attr;
2092 :
2093 4 : if (attr->ref != NULL) {
2094 4 : if (ctx->attributeGroups != NULL) {
2095 4 : if (zend_hash_find(ctx->attributeGroups, attr->ref, strlen(attr->ref)+1, (void**)&tmp) == SUCCESS) {
2096 4 : if ((*tmp)->attributes) {
2097 4 : zend_hash_internal_pointer_reset((*tmp)->attributes);
2098 12 : while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
2099 4 : if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
2100 : char* key;
2101 : uint key_len;
2102 : sdlAttributePtr newAttr;
2103 :
2104 4 : schema_attribute_fixup(ctx,*tmp_attr);
2105 :
2106 4 : newAttr = emalloc(sizeof(sdlAttribute));
2107 4 : memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
2108 4 : if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
2109 4 : if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
2110 4 : if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
2111 4 : if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
2112 4 : if (newAttr->extraAttributes) {
2113 : xmlNodePtr node;
2114 0 : HashTable *ht = emalloc(sizeof(HashTable));
2115 0 : zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
2116 0 : zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
2117 0 : newAttr->extraAttributes = ht;
2118 : }
2119 :
2120 4 : zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
2121 4 : zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
2122 :
2123 4 : zend_hash_move_forward((*tmp)->attributes);
2124 : } else {
2125 : ulong index;
2126 :
2127 0 : schema_attributegroup_fixup(ctx,*tmp_attr, ht);
2128 0 : zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
2129 0 : zend_hash_index_del((*tmp)->attributes, index);
2130 : }
2131 : }
2132 : }
2133 : }
2134 : }
2135 4 : efree(attr->ref);
2136 4 : attr->ref = NULL;
2137 : }
2138 4 : }
2139 :
2140 : static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
2141 14523 : {
2142 14523 : switch (model->kind) {
2143 : case XSD_CONTENT_GROUP_REF: {
2144 : sdlTypePtr *tmp;
2145 :
2146 4 : if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
2147 2 : schema_type_fixup(ctx,*tmp);
2148 2 : efree(model->u.group_ref);
2149 2 : model->kind = XSD_CONTENT_GROUP;
2150 2 : model->u.group = (*tmp);
2151 : } else {
2152 0 : soap_error0(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute");
2153 : }
2154 2 : break;
2155 : }
2156 : case XSD_CONTENT_CHOICE: {
2157 92 : if (model->max_occurs != 1) {
2158 : HashPosition pos;
2159 : sdlContentModelPtr *tmp;
2160 :
2161 18 : zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
2162 156 : while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
2163 120 : (*tmp)->min_occurs = 0;
2164 120 : (*tmp)->max_occurs = model->max_occurs;
2165 120 : zend_hash_move_forward_ex(model->u.content, &pos);
2166 : }
2167 :
2168 18 : model->kind = XSD_CONTENT_ALL;
2169 18 : model->min_occurs = 1;
2170 18 : model->max_occurs = 1;
2171 : }
2172 : }
2173 : case XSD_CONTENT_SEQUENCE:
2174 : case XSD_CONTENT_ALL: {
2175 : sdlContentModelPtr *tmp;
2176 :
2177 5724 : zend_hash_internal_pointer_reset(model->u.content);
2178 20339 : while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
2179 8891 : schema_content_model_fixup(ctx, *tmp);
2180 8891 : zend_hash_move_forward(model->u.content);
2181 : }
2182 : break;
2183 : }
2184 : default:
2185 : break;
2186 : }
2187 14523 : }
2188 :
2189 : static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
2190 23110 : {
2191 : sdlTypePtr *tmp;
2192 : sdlAttributePtr *attr;
2193 :
2194 23110 : if (type->ref != NULL) {
2195 160 : if (ctx->sdl->elements != NULL) {
2196 160 : if (zend_hash_find(ctx->sdl->elements, type->ref, strlen(type->ref)+1, (void**)&tmp) == SUCCESS) {
2197 158 : type->kind = (*tmp)->kind;
2198 158 : type->encode = (*tmp)->encode;
2199 158 : if ((*tmp)->nillable) {
2200 72 : type->nillable = 1;
2201 : }
2202 158 : if ((*tmp)->fixed) {
2203 0 : type->fixed = estrdup((*tmp)->fixed);
2204 : }
2205 158 : if ((*tmp)->def) {
2206 0 : type->def = estrdup((*tmp)->def);
2207 : }
2208 158 : type->form = (*tmp)->form;
2209 2 : } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
2210 2 : type->encode = get_conversion(XSD_ANYXML);
2211 : } else {
2212 0 : soap_error0(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute");
2213 : }
2214 : }
2215 160 : efree(type->ref);
2216 160 : type->ref = NULL;
2217 : }
2218 23110 : if (type->elements) {
2219 5530 : zend_hash_internal_pointer_reset(type->elements);
2220 19788 : while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
2221 8728 : schema_type_fixup(ctx,*tmp);
2222 8728 : zend_hash_move_forward(type->elements);
2223 : }
2224 : }
2225 23110 : if (type->model) {
2226 5632 : schema_content_model_fixup(ctx, type->model);
2227 : }
2228 23110 : if (type->attributes) {
2229 1248 : zend_hash_internal_pointer_reset(type->attributes);
2230 4232 : while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
2231 1736 : if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
2232 1732 : schema_attribute_fixup(ctx,*attr);
2233 1732 : zend_hash_move_forward(type->attributes);
2234 : } else {
2235 : ulong index;
2236 :
2237 4 : schema_attributegroup_fixup(ctx,*attr,type->attributes);
2238 4 : zend_hash_get_current_key(type->attributes, NULL, &index, 0);
2239 4 : zend_hash_index_del(type->attributes, index);
2240 : }
2241 : }
2242 : }
2243 23110 : }
2244 :
2245 : void schema_pass2(sdlCtx *ctx)
2246 693 : {
2247 693 : sdlPtr sdl = ctx->sdl;
2248 : sdlAttributePtr *attr;
2249 : sdlTypePtr *type;
2250 :
2251 693 : if (ctx->attributes) {
2252 671 : zend_hash_internal_pointer_reset(ctx->attributes);
2253 1360 : while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
2254 18 : schema_attribute_fixup(ctx,*attr);
2255 18 : zend_hash_move_forward(ctx->attributes);
2256 : }
2257 : }
2258 693 : if (ctx->attributeGroups) {
2259 671 : zend_hash_internal_pointer_reset(ctx->attributeGroups);
2260 1351 : while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
2261 9 : schema_type_fixup(ctx,*type);
2262 9 : zend_hash_move_forward(ctx->attributeGroups);
2263 : }
2264 : }
2265 693 : if (sdl->elements) {
2266 274 : zend_hash_internal_pointer_reset(sdl->elements);
2267 6958 : while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
2268 6410 : schema_type_fixup(ctx,*type);
2269 6410 : zend_hash_move_forward(sdl->elements);
2270 : }
2271 : }
2272 693 : if (sdl->groups) {
2273 2 : zend_hash_internal_pointer_reset(sdl->groups);
2274 6 : while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
2275 2 : schema_type_fixup(ctx,*type);
2276 2 : zend_hash_move_forward(sdl->groups);
2277 : }
2278 : }
2279 693 : if (sdl->types) {
2280 671 : zend_hash_internal_pointer_reset(sdl->types);
2281 9301 : while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
2282 7959 : schema_type_fixup(ctx,*type);
2283 7959 : zend_hash_move_forward(sdl->types);
2284 : }
2285 : }
2286 693 : if (ctx->attributes) {
2287 671 : zend_hash_destroy(ctx->attributes);
2288 671 : efree(ctx->attributes);
2289 : }
2290 693 : if (ctx->attributeGroups) {
2291 671 : zend_hash_destroy(ctx->attributeGroups);
2292 671 : efree(ctx->attributeGroups);
2293 : }
2294 693 : }
2295 :
2296 : void delete_model(void *handle)
2297 14524 : {
2298 14524 : sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
2299 14524 : switch (tmp->kind) {
2300 : case XSD_CONTENT_ELEMENT:
2301 : case XSD_CONTENT_GROUP:
2302 8654 : break;
2303 : case XSD_CONTENT_SEQUENCE:
2304 : case XSD_CONTENT_ALL:
2305 : case XSD_CONTENT_CHOICE:
2306 5723 : zend_hash_destroy(tmp->u.content);
2307 5723 : efree(tmp->u.content);
2308 5723 : break;
2309 : case XSD_CONTENT_GROUP_REF:
2310 0 : efree(tmp->u.group_ref);
2311 : break;
2312 : default:
2313 : break;
2314 : }
2315 14524 : efree(tmp);
2316 14524 : }
2317 :
2318 : void delete_model_persistent(void *handle)
2319 23 : {
2320 23 : sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
2321 23 : switch (tmp->kind) {
2322 : case XSD_CONTENT_ELEMENT:
2323 : case XSD_CONTENT_GROUP:
2324 17 : break;
2325 : case XSD_CONTENT_SEQUENCE:
2326 : case XSD_CONTENT_ALL:
2327 : case XSD_CONTENT_CHOICE:
2328 6 : zend_hash_destroy(tmp->u.content);
2329 6 : free(tmp->u.content);
2330 6 : break;
2331 : case XSD_CONTENT_GROUP_REF:
2332 0 : free(tmp->u.group_ref);
2333 : break;
2334 : default:
2335 : break;
2336 : }
2337 23 : free(tmp);
2338 23 : }
2339 :
2340 : void delete_type(void *data)
2341 23121 : {
2342 23121 : sdlTypePtr type = *((sdlTypePtr*)data);
2343 :
2344 23121 : if (type->name) {
2345 23119 : efree(type->name);
2346 : }
2347 23121 : if (type->namens) {
2348 23119 : efree(type->namens);
2349 : }
2350 23121 : if (type->def) {
2351 3 : efree(type->def);
2352 : }
2353 23121 : if (type->fixed) {
2354 0 : efree(type->fixed);
2355 : }
2356 23121 : if (type->elements) {
2357 5531 : zend_hash_destroy(type->elements);
2358 5531 : efree(type->elements);
2359 : }
2360 23121 : if (type->attributes) {
2361 1248 : zend_hash_destroy(type->attributes);
2362 1248 : efree(type->attributes);
2363 : }
2364 23121 : if (type->model) {
2365 5633 : delete_model((void**)&type->model);
2366 : }
2367 23121 : if (type->restrictions) {
2368 350 : delete_restriction_var_int(&type->restrictions->minExclusive);
2369 350 : delete_restriction_var_int(&type->restrictions->minInclusive);
2370 350 : delete_restriction_var_int(&type->restrictions->maxExclusive);
2371 350 : delete_restriction_var_int(&type->restrictions->maxInclusive);
2372 350 : delete_restriction_var_int(&type->restrictions->totalDigits);
2373 350 : delete_restriction_var_int(&type->restrictions->fractionDigits);
2374 350 : delete_restriction_var_int(&type->restrictions->length);
2375 350 : delete_restriction_var_int(&type->restrictions->minLength);
2376 350 : delete_restriction_var_int(&type->restrictions->maxLength);
2377 350 : delete_restriction_var_char(&type->restrictions->whiteSpace);
2378 350 : delete_restriction_var_char(&type->restrictions->pattern);
2379 350 : if (type->restrictions->enumeration) {
2380 281 : zend_hash_destroy(type->restrictions->enumeration);
2381 281 : efree(type->restrictions->enumeration);
2382 : }
2383 350 : efree(type->restrictions);
2384 : }
2385 23121 : efree(type);
2386 23121 : }
2387 :
2388 : void delete_type_persistent(void *data)
2389 25 : {
2390 25 : sdlTypePtr type = *((sdlTypePtr*)data);
2391 25 : if (type->name) {
2392 25 : free(type->name);
2393 : }
2394 25 : if (type->namens) {
2395 25 : free(type->namens);
2396 : }
2397 25 : if (type->def) {
2398 0 : free(type->def);
2399 : }
2400 25 : if (type->fixed) {
2401 0 : free(type->fixed);
2402 : }
2403 25 : if (type->elements) {
2404 6 : zend_hash_destroy(type->elements);
2405 6 : free(type->elements);
2406 : }
2407 25 : if (type->attributes) {
2408 2 : zend_hash_destroy(type->attributes);
2409 2 : free(type->attributes);
2410 : }
2411 25 : if (type->model) {
2412 6 : delete_model_persistent((void**)&type->model);
2413 : }
2414 25 : if (type->restrictions) {
2415 0 : delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
2416 0 : delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
2417 0 : delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
2418 0 : delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
2419 0 : delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
2420 0 : delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
2421 0 : delete_restriction_var_int_persistent(&type->restrictions->length);
2422 0 : delete_restriction_var_int_persistent(&type->restrictions->minLength);
2423 0 : delete_restriction_var_int_persistent(&type->restrictions->maxLength);
2424 0 : delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
2425 0 : delete_restriction_var_char_persistent(&type->restrictions->pattern);
2426 0 : if (type->restrictions->enumeration) {
2427 0 : zend_hash_destroy(type->restrictions->enumeration);
2428 0 : free(type->restrictions->enumeration);
2429 : }
2430 0 : free(type->restrictions);
2431 : }
2432 25 : free(type);
2433 25 : }
2434 :
2435 : void delete_extra_attribute(void *attribute)
2436 1041 : {
2437 1041 : sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
2438 :
2439 1041 : if (attr->ns) {
2440 1040 : efree(attr->ns);
2441 : }
2442 1041 : if (attr->val) {
2443 1041 : efree(attr->val);
2444 : }
2445 1041 : efree(attr);
2446 1041 : }
2447 :
2448 : void delete_extra_attribute_persistent(void *attribute)
2449 0 : {
2450 0 : sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
2451 :
2452 0 : if (attr->ns) {
2453 0 : free(attr->ns);
2454 : }
2455 0 : if (attr->val) {
2456 0 : free(attr->val);
2457 : }
2458 0 : free(attr);
2459 0 : }
2460 :
2461 : void delete_attribute(void *attribute)
2462 1754 : {
2463 1754 : sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
2464 :
2465 1754 : if (attr->def) {
2466 44 : efree(attr->def);
2467 : }
2468 1754 : if (attr->fixed) {
2469 7 : efree(attr->fixed);
2470 : }
2471 1754 : if (attr->name) {
2472 1717 : efree(attr->name);
2473 : }
2474 1754 : if (attr->namens) {
2475 1749 : efree(attr->namens);
2476 : }
2477 1754 : if (attr->ref) {
2478 0 : efree(attr->ref);
2479 : }
2480 1754 : if (attr->extraAttributes) {
2481 970 : zend_hash_destroy(attr->extraAttributes);
2482 970 : efree(attr->extraAttributes);
2483 : }
2484 1754 : efree(attr);
2485 1754 : }
2486 :
2487 : void delete_attribute_persistent(void *attribute)
2488 2 : {
2489 2 : sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
2490 :
2491 2 : if (attr->def) {
2492 0 : free(attr->def);
2493 : }
2494 2 : if (attr->fixed) {
2495 0 : free(attr->fixed);
2496 : }
2497 2 : if (attr->name) {
2498 2 : free(attr->name);
2499 : }
2500 2 : if (attr->namens) {
2501 2 : free(attr->namens);
2502 : }
2503 2 : if (attr->ref) {
2504 0 : free(attr->ref);
2505 : }
2506 2 : if (attr->extraAttributes) {
2507 2 : zend_hash_destroy(attr->extraAttributes);
2508 2 : free(attr->extraAttributes);
2509 : }
2510 2 : free(attr);
2511 2 : }
2512 :
2513 : void delete_restriction_var_int(void *rvi)
2514 3150 : {
2515 3150 : sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
2516 3150 : if (ptr) {
2517 5 : efree(ptr);
2518 : }
2519 3150 : }
2520 :
2521 : void delete_restriction_var_int_persistent(void *rvi)
2522 0 : {
2523 0 : sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
2524 0 : if (ptr) {
2525 0 : free(ptr);
2526 : }
2527 0 : }
2528 :
2529 : void delete_restriction_var_char(void *srvc)
2530 1598 : {
2531 1598 : sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
2532 1598 : if (ptr) {
2533 903 : if (ptr->value) {
2534 903 : efree(ptr->value);
2535 : }
2536 903 : efree(ptr);
2537 : }
2538 1598 : }
2539 :
2540 : void delete_restriction_var_char_persistent(void *srvc)
2541 0 : {
2542 0 : sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
2543 0 : if (ptr) {
2544 0 : if (ptr->value) {
2545 0 : free(ptr->value);
2546 : }
2547 0 : free(ptr);
2548 : }
2549 0 : }
|