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