File: | libs/apr-util/xml/apr_xml.c |
Location: | line 85, column 20 |
Description: | Value stored to 'ns_scope' during its initialization is never read |
1 | /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as |
2 | * applicable. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #include "apr.h" |
18 | #include "apr_strings.h" |
19 | |
20 | #define APR_WANT_STDIO /* for sprintf() */ |
21 | #define APR_WANT_STRFUNC |
22 | #include "apr_want.h" |
23 | |
24 | #include "apr_xml.h" |
25 | |
26 | #include "apu_config.h" |
27 | |
28 | #ifdef APR_HAVE_OLD_EXPAT |
29 | #include "xmlparse.h" |
30 | #else |
31 | #include "expat.h" |
32 | #endif |
33 | |
34 | #define DEBUG_CR"\r\n" "\r\n" |
35 | |
36 | static const char APR_KW_xmlns[] = { 0x78, 0x6D, 0x6C, 0x6E, 0x73, '\0' }; |
37 | static const char APR_KW_xmlns_lang[] = { 0x78, 0x6D, 0x6C, 0x3A, 0x6C, 0x61, 0x6E, 0x67, '\0' }; |
38 | static const char APR_KW_DAV[] = { 0x44, 0x41, 0x56, 0x3A, '\0' }; |
39 | |
40 | /* errors related to namespace processing */ |
41 | #define APR_XML_NS_ERROR_UNKNOWN_PREFIX(-1000) (-1000) |
42 | #define APR_XML_NS_ERROR_INVALID_DECL(-1001) (-1001) |
43 | |
44 | /* test for a namespace prefix that begins with [Xx][Mm][Ll] */ |
45 | #define APR_XML_NS_IS_RESERVED(name)( (name[0] == 0x58 || name[0] == 0x78) && (name[1] == 0x4D || name[1] == 0x6D) && (name[2] == 0x4C || name [2] == 0x6C) ) \ |
46 | ( (name[0] == 0x58 || name[0] == 0x78) && \ |
47 | (name[1] == 0x4D || name[1] == 0x6D) && \ |
48 | (name[2] == 0x4C || name[2] == 0x6C) ) |
49 | |
50 | |
51 | /* the real (internal) definition of the parser context */ |
52 | struct apr_xml_parser { |
53 | apr_xml_doc *doc; /* the doc we're parsing */ |
54 | apr_pool_t *p; /* the pool we allocate from */ |
55 | apr_xml_elem *cur_elem; /* current element */ |
56 | |
57 | int error; /* an error has occurred */ |
58 | #define APR_XML_ERROR_EXPAT1 1 |
59 | #define APR_XML_ERROR_PARSE_DONE2 2 |
60 | /* also: public APR_XML_NS_ERROR_* values (if any) */ |
61 | |
62 | XML_Parser xp; /* the actual (Expat) XML parser */ |
63 | enum XML_Error xp_err; /* stored Expat error code */ |
64 | }; |
65 | |
66 | /* struct for scoping namespace declarations */ |
67 | typedef struct apr_xml_ns_scope { |
68 | const char *prefix; /* prefix used for this ns */ |
69 | int ns; /* index into namespace table */ |
70 | int emptyURI; /* the namespace URI is the empty string */ |
71 | struct apr_xml_ns_scope *next; /* next scoped namespace */ |
72 | } apr_xml_ns_scope; |
73 | |
74 | |
75 | /* return namespace table index for a given prefix */ |
76 | static int find_prefix(apr_xml_parser *parser, const char *prefix) |
77 | { |
78 | apr_xml_elem *elem = parser->cur_elem; |
79 | |
80 | /* |
81 | ** Walk up the tree, looking for a namespace scope that defines this |
82 | ** prefix. |
83 | */ |
84 | for (; elem; elem = elem->parent) { |
85 | apr_xml_ns_scope *ns_scope = elem->ns_scope; |
Value stored to 'ns_scope' during its initialization is never read | |
86 | |
87 | for (ns_scope = elem->ns_scope; ns_scope; ns_scope = ns_scope->next) { |
88 | if (strcmp(prefix, ns_scope->prefix)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (prefix) && __builtin_constant_p (ns_scope->prefix ) && (__s1_len = __builtin_strlen (prefix), __s2_len = __builtin_strlen (ns_scope->prefix), (!((size_t)(const void *)((prefix) + 1) - (size_t)(const void *)(prefix) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((ns_scope-> prefix) + 1) - (size_t)(const void *)(ns_scope->prefix) == 1) || __s2_len >= 4)) ? __builtin_strcmp (prefix, ns_scope ->prefix) : (__builtin_constant_p (prefix) && ((size_t )(const void *)((prefix) + 1) - (size_t)(const void *)(prefix ) == 1) && (__s1_len = __builtin_strlen (prefix), __s1_len < 4) ? (__builtin_constant_p (ns_scope->prefix) && ((size_t)(const void *)((ns_scope->prefix) + 1) - (size_t )(const void *)(ns_scope->prefix) == 1) ? __builtin_strcmp (prefix, ns_scope->prefix) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (ns_scope ->prefix); int __result = (((const unsigned char *) (const char *) (prefix))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (prefix))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (prefix))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (prefix))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (ns_scope->prefix) && ((size_t)(const void *)((ns_scope ->prefix) + 1) - (size_t)(const void *)(ns_scope->prefix ) == 1) && (__s2_len = __builtin_strlen (ns_scope-> prefix), __s2_len < 4) ? (__builtin_constant_p (prefix) && ((size_t)(const void *)((prefix) + 1) - (size_t)(const void * )(prefix) == 1) ? __builtin_strcmp (prefix, ns_scope->prefix ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (prefix); int __result = (((const unsigned char *) (const char *) (ns_scope->prefix))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = ( ((const unsigned char *) (const char *) (ns_scope->prefix) )[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (ns_scope ->prefix))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (ns_scope ->prefix))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (prefix, ns_scope->prefix)))); }) == 0) { |
89 | if (ns_scope->emptyURI) { |
90 | /* |
91 | ** It is possible to set the default namespace to an |
92 | ** empty URI string; this resets the default namespace |
93 | ** to mean "no namespace." We just found the prefix |
94 | ** refers to an empty URI, so return "no namespace." |
95 | */ |
96 | return APR_XML_NS_NONE-10; |
97 | } |
98 | |
99 | return ns_scope->ns; |
100 | } |
101 | } |
102 | } |
103 | |
104 | /* |
105 | * If the prefix is empty (""), this means that a prefix was not |
106 | * specified in the element/attribute. The search that was performed |
107 | * just above did not locate a default namespace URI (which is stored |
108 | * into ns_scope with an empty prefix). This means the element/attribute |
109 | * has "no namespace". We have a reserved value for this. |
110 | */ |
111 | if (*prefix == '\0') { |
112 | return APR_XML_NS_NONE-10; |
113 | } |
114 | |
115 | /* not found */ |
116 | return APR_XML_NS_ERROR_UNKNOWN_PREFIX(-1000); |
117 | } |
118 | |
119 | static void start_handler(void *userdata, const char *name, const char **attrs) |
120 | { |
121 | apr_xml_parser *parser = userdata; |
122 | apr_xml_elem *elem; |
123 | apr_xml_attr *attr; |
124 | apr_xml_attr *prev; |
125 | char *colon; |
126 | const char *quoted; |
127 | char *elem_name; |
128 | |
129 | /* punt once we find an error */ |
130 | if (parser->error) |
131 | return; |
132 | |
133 | elem = apr_pcalloc(parser->p, sizeof(*elem))memset(apr_palloc(parser->p, sizeof(*elem)), 0, sizeof(*elem )); |
134 | |
135 | /* prep the element */ |
136 | elem->name = elem_name = apr_pstrdup(parser->p, name); |
137 | |
138 | /* fill in the attributes (note: ends up in reverse order) */ |
139 | while (*attrs) { |
140 | attr = apr_palloc(parser->p, sizeof(*attr)); |
141 | attr->name = apr_pstrdup(parser->p, *attrs++); |
142 | attr->value = apr_pstrdup(parser->p, *attrs++); |
143 | attr->next = elem->attr; |
144 | elem->attr = attr; |
145 | } |
146 | |
147 | /* hook the element into the tree */ |
148 | if (parser->cur_elem == NULL((void*)0)) { |
149 | /* no current element; this also becomes the root */ |
150 | parser->cur_elem = parser->doc->root = elem; |
151 | } |
152 | else { |
153 | /* this element appeared within the current elem */ |
154 | elem->parent = parser->cur_elem; |
155 | |
156 | /* set up the child/sibling links */ |
157 | if (elem->parent->last_child == NULL((void*)0)) { |
158 | /* no first child either */ |
159 | elem->parent->first_child = elem->parent->last_child = elem; |
160 | } |
161 | else { |
162 | /* hook onto the end of the parent's children */ |
163 | elem->parent->last_child->next = elem; |
164 | elem->parent->last_child = elem; |
165 | } |
166 | |
167 | /* this element is now the current element */ |
168 | parser->cur_elem = elem; |
169 | } |
170 | |
171 | /* scan the attributes for namespace declarations */ |
172 | for (prev = NULL((void*)0), attr = elem->attr; |
173 | attr; |
174 | attr = attr->next) { |
175 | if (strncmp(attr->name, APR_KW_xmlns, 5)(__extension__ (__builtin_constant_p (5) && ((__builtin_constant_p (attr->name) && strlen (attr->name) < ((size_t ) (5))) || (__builtin_constant_p (APR_KW_xmlns) && strlen (APR_KW_xmlns) < ((size_t) (5)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (attr->name) && __builtin_constant_p (APR_KW_xmlns) && (__s1_len = __builtin_strlen (attr->name), __s2_len = __builtin_strlen (APR_KW_xmlns), (!((size_t)(const void *)((attr->name) + 1) - (size_t)(const void *)(attr->name) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((APR_KW_xmlns) + 1) - (size_t)(const void *)(APR_KW_xmlns) == 1) || __s2_len >= 4)) ? __builtin_strcmp (attr->name, APR_KW_xmlns) : (__builtin_constant_p (attr-> name) && ((size_t)(const void *)((attr->name) + 1) - (size_t)(const void *)(attr->name) == 1) && (__s1_len = __builtin_strlen (attr->name), __s1_len < 4) ? (__builtin_constant_p (APR_KW_xmlns) && ((size_t)(const void *)((APR_KW_xmlns ) + 1) - (size_t)(const void *)(APR_KW_xmlns) == 1) ? __builtin_strcmp (attr->name, APR_KW_xmlns) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (APR_KW_xmlns ); int __result = (((const unsigned char *) (const char *) (attr ->name))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( attr->name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (attr->name))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (attr->name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (APR_KW_xmlns) && ((size_t)(const void *)((APR_KW_xmlns ) + 1) - (size_t)(const void *)(APR_KW_xmlns) == 1) && (__s2_len = __builtin_strlen (APR_KW_xmlns), __s2_len < 4 ) ? (__builtin_constant_p (attr->name) && ((size_t )(const void *)((attr->name) + 1) - (size_t)(const void *) (attr->name) == 1) ? __builtin_strcmp (attr->name, APR_KW_xmlns ) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (attr->name); int __result = (((const unsigned char *) (const char *) (APR_KW_xmlns))[0] - __s2[0] ); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (APR_KW_xmlns))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (APR_KW_xmlns))[2 ] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (APR_KW_xmlns))[3 ] - __s2[3]); } } __result; })))) : __builtin_strcmp (attr-> name, APR_KW_xmlns)))); }) : strncmp (attr->name, APR_KW_xmlns , 5))) == 0) { |
176 | const char *prefix = &attr->name[5]; |
177 | apr_xml_ns_scope *ns_scope; |
178 | |
179 | /* test for xmlns:foo= form and xmlns= form */ |
180 | if (*prefix == 0x3A) { |
181 | /* a namespace prefix declaration must have a |
182 | non-empty value. */ |
183 | if (attr->value[0] == '\0') { |
184 | parser->error = APR_XML_NS_ERROR_INVALID_DECL(-1001); |
185 | return; |
186 | } |
187 | ++prefix; |
188 | } |
189 | else if (*prefix != '\0') { |
190 | /* advance "prev" since "attr" is still present */ |
191 | prev = attr; |
192 | continue; |
193 | } |
194 | |
195 | /* quote the URI before we ever start working with it */ |
196 | quoted = apr_xml_quote_string(parser->p, attr->value, 1); |
197 | |
198 | /* build and insert the new scope */ |
199 | ns_scope = apr_pcalloc(parser->p, sizeof(*ns_scope))memset(apr_palloc(parser->p, sizeof(*ns_scope)), 0, sizeof (*ns_scope)); |
200 | ns_scope->prefix = prefix; |
201 | ns_scope->ns = apr_xml_insert_uri(parser->doc->namespaces, quoted); |
202 | ns_scope->emptyURI = *quoted == '\0'; |
203 | ns_scope->next = elem->ns_scope; |
204 | elem->ns_scope = ns_scope; |
205 | |
206 | /* remove this attribute from the element */ |
207 | if (prev == NULL((void*)0)) |
208 | elem->attr = attr->next; |
209 | else |
210 | prev->next = attr->next; |
211 | |
212 | /* Note: prev will not be advanced since we just removed "attr" */ |
213 | } |
214 | else if (strcmp(attr->name, APR_KW_xmlns_lang)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (attr->name) && __builtin_constant_p (APR_KW_xmlns_lang ) && (__s1_len = __builtin_strlen (attr->name), __s2_len = __builtin_strlen (APR_KW_xmlns_lang), (!((size_t)(const void *)((attr->name) + 1) - (size_t)(const void *)(attr->name ) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((APR_KW_xmlns_lang) + 1) - (size_t)(const void *)(APR_KW_xmlns_lang ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (attr->name , APR_KW_xmlns_lang) : (__builtin_constant_p (attr->name) && ((size_t)(const void *)((attr->name) + 1) - (size_t)(const void *)(attr->name) == 1) && (__s1_len = __builtin_strlen (attr->name), __s1_len < 4) ? (__builtin_constant_p (APR_KW_xmlns_lang ) && ((size_t)(const void *)((APR_KW_xmlns_lang) + 1) - (size_t)(const void *)(APR_KW_xmlns_lang) == 1) ? __builtin_strcmp (attr->name, APR_KW_xmlns_lang) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (APR_KW_xmlns_lang); int __result = (((const unsigned char * ) (const char *) (attr->name))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (attr->name))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (attr->name))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (attr->name))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (APR_KW_xmlns_lang) && ((size_t)(const void *)((APR_KW_xmlns_lang) + 1) - (size_t)( const void *)(APR_KW_xmlns_lang) == 1) && (__s2_len = __builtin_strlen (APR_KW_xmlns_lang), __s2_len < 4) ? (__builtin_constant_p (attr->name) && ((size_t)(const void *)((attr-> name) + 1) - (size_t)(const void *)(attr->name) == 1) ? __builtin_strcmp (attr->name, APR_KW_xmlns_lang) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (attr->name); int __result = (((const unsigned char *) (const char *) (APR_KW_xmlns_lang))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (APR_KW_xmlns_lang))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (APR_KW_xmlns_lang))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (APR_KW_xmlns_lang))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (attr->name, APR_KW_xmlns_lang )))); }) == 0) { |
215 | /* save away the language (in quoted form) */ |
216 | elem->lang = apr_xml_quote_string(parser->p, attr->value, 1); |
217 | |
218 | /* remove this attribute from the element */ |
219 | if (prev == NULL((void*)0)) |
220 | elem->attr = attr->next; |
221 | else |
222 | prev->next = attr->next; |
223 | |
224 | /* Note: prev will not be advanced since we just removed "attr" */ |
225 | } |
226 | else { |
227 | /* advance "prev" since "attr" is still present */ |
228 | prev = attr; |
229 | } |
230 | } |
231 | |
232 | /* |
233 | ** If an xml:lang attribute didn't exist (lang==NULL), then copy the |
234 | ** language from the parent element (if present). |
235 | ** |
236 | ** NOTE: elem_size() *depends* upon this pointer equality. |
237 | */ |
238 | if (elem->lang == NULL((void*)0) && elem->parent != NULL((void*)0)) |
239 | elem->lang = elem->parent->lang; |
240 | |
241 | /* adjust the element's namespace */ |
242 | colon = strchr(elem_name, 0x3A)(__extension__ (__builtin_constant_p (0x3A) && !__builtin_constant_p (elem_name) && (0x3A) == '\0' ? (char *) __rawmemchr (elem_name, 0x3A) : __builtin_strchr (elem_name, 0x3A))); |
243 | if (colon == NULL((void*)0)) { |
244 | /* |
245 | * The element is using the default namespace, which will always |
246 | * be found. Either it will be "no namespace", or a default |
247 | * namespace URI has been specified at some point. |
248 | */ |
249 | elem->ns = find_prefix(parser, ""); |
250 | } |
251 | else if (APR_XML_NS_IS_RESERVED(elem->name)( (elem->name[0] == 0x58 || elem->name[0] == 0x78) && (elem->name[1] == 0x4D || elem->name[1] == 0x6D) && (elem->name[2] == 0x4C || elem->name[2] == 0x6C) )) { |
252 | elem->ns = APR_XML_NS_NONE-10; |
253 | } |
254 | else { |
255 | *colon = '\0'; |
256 | elem->ns = find_prefix(parser, elem->name); |
257 | elem->name = colon + 1; |
258 | |
259 | if (APR_XML_NS_IS_ERROR(elem->ns)((elem->ns) <= -100)) { |
260 | parser->error = elem->ns; |
261 | return; |
262 | } |
263 | } |
264 | |
265 | /* adjust all remaining attributes' namespaces */ |
266 | for (attr = elem->attr; attr; attr = attr->next) { |
267 | /* |
268 | * apr_xml_attr defines this as "const" but we dup'd it, so we |
269 | * know that we can change it. a bit hacky, but the existing |
270 | * structure def is best. |
271 | */ |
272 | char *attr_name = (char *)attr->name; |
273 | |
274 | colon = strchr(attr_name, 0x3A)(__extension__ (__builtin_constant_p (0x3A) && !__builtin_constant_p (attr_name) && (0x3A) == '\0' ? (char *) __rawmemchr (attr_name, 0x3A) : __builtin_strchr (attr_name, 0x3A))); |
275 | if (colon == NULL((void*)0)) { |
276 | /* |
277 | * Attributes do NOT use the default namespace. Therefore, |
278 | * we place them into the "no namespace" category. |
279 | */ |
280 | attr->ns = APR_XML_NS_NONE-10; |
281 | } |
282 | else if (APR_XML_NS_IS_RESERVED(attr->name)( (attr->name[0] == 0x58 || attr->name[0] == 0x78) && (attr->name[1] == 0x4D || attr->name[1] == 0x6D) && (attr->name[2] == 0x4C || attr->name[2] == 0x6C) )) { |
283 | attr->ns = APR_XML_NS_NONE-10; |
284 | } |
285 | else { |
286 | *colon = '\0'; |
287 | attr->ns = find_prefix(parser, attr->name); |
288 | attr->name = colon + 1; |
289 | |
290 | if (APR_XML_NS_IS_ERROR(attr->ns)((attr->ns) <= -100)) { |
291 | parser->error = attr->ns; |
292 | return; |
293 | } |
294 | } |
295 | } |
296 | } |
297 | |
298 | static void end_handler(void *userdata, const char *name) |
299 | { |
300 | apr_xml_parser *parser = userdata; |
301 | |
302 | /* punt once we find an error */ |
303 | if (parser->error) |
304 | return; |
305 | |
306 | /* pop up one level */ |
307 | parser->cur_elem = parser->cur_elem->parent; |
308 | } |
309 | |
310 | static void cdata_handler(void *userdata, const char *data, int len) |
311 | { |
312 | apr_xml_parser *parser = userdata; |
313 | apr_xml_elem *elem; |
314 | apr_text_header *hdr; |
315 | const char *s; |
316 | |
317 | /* punt once we find an error */ |
318 | if (parser->error) |
319 | return; |
320 | |
321 | elem = parser->cur_elem; |
322 | s = apr_pstrndup(parser->p, data, len); |
323 | |
324 | if (elem->last_child == NULL((void*)0)) { |
325 | /* no children yet. this cdata follows the start tag */ |
326 | hdr = &elem->first_cdata; |
327 | } |
328 | else { |
329 | /* child elements exist. this cdata follows the last child. */ |
330 | hdr = &elem->last_child->following_cdata; |
331 | } |
332 | |
333 | apr_text_append(parser->p, hdr, s); |
334 | } |
335 | |
336 | static apr_status_t cleanup_parser(void *ctx) |
337 | { |
338 | apr_xml_parser *parser = ctx; |
339 | |
340 | XML_ParserFree(parser->xp); |
341 | parser->xp = NULL((void*)0); |
342 | |
343 | return APR_SUCCESS0; |
344 | } |
345 | |
346 | APU_DECLARE(apr_xml_parser *)apr_xml_parser * apr_xml_parser_create(apr_pool_t *pool) |
347 | { |
348 | apr_xml_parser *parser = apr_pcalloc(pool, sizeof(*parser))memset(apr_palloc(pool, sizeof(*parser)), 0, sizeof(*parser)); |
349 | |
350 | parser->p = pool; |
351 | parser->doc = apr_pcalloc(pool, sizeof(*parser->doc))memset(apr_palloc(pool, sizeof(*parser->doc)), 0, sizeof(* parser->doc)); |
352 | |
353 | parser->doc->namespaces = apr_array_make(pool, 5, sizeof(const char *)); |
354 | |
355 | /* ### is there a way to avoid hard-coding this? */ |
356 | apr_xml_insert_uri(parser->doc->namespaces, APR_KW_DAV); |
357 | |
358 | parser->xp = XML_ParserCreate(NULL((void*)0)); |
359 | if (parser->xp == NULL((void*)0)) { |
360 | (*apr_pool_abort_get(pool))(APR_ENOMEM12); |
361 | return NULL((void*)0); |
362 | } |
363 | |
364 | apr_pool_cleanup_register(pool, parser, cleanup_parser, |
365 | apr_pool_cleanup_null); |
366 | |
367 | XML_SetUserData(parser->xp, parser); |
368 | XML_SetElementHandler(parser->xp, start_handler, end_handler); |
369 | XML_SetCharacterDataHandler(parser->xp, cdata_handler); |
370 | |
371 | return parser; |
372 | } |
373 | |
374 | static apr_status_t do_parse(apr_xml_parser *parser, |
375 | const char *data, apr_size_t len, |
376 | int is_final) |
377 | { |
378 | if (parser->xp == NULL((void*)0)) { |
379 | parser->error = APR_XML_ERROR_PARSE_DONE2; |
380 | } |
381 | else { |
382 | int rv = XML_Parse(parser->xp, data, len, is_final); |
383 | |
384 | if (rv == 0) { |
385 | parser->error = APR_XML_ERROR_EXPAT1; |
386 | parser->xp_err = XML_GetErrorCode(parser->xp); |
387 | } |
388 | } |
389 | |
390 | /* ### better error code? */ |
391 | return parser->error ? APR_EGENERAL(20000 + 14) : APR_SUCCESS0; |
392 | } |
393 | |
394 | APU_DECLARE(apr_status_t)apr_status_t apr_xml_parser_feed(apr_xml_parser *parser, |
395 | const char *data, |
396 | apr_size_t len) |
397 | { |
398 | return do_parse(parser, data, len, 0 /* is_final */); |
399 | } |
400 | |
401 | APU_DECLARE(apr_status_t)apr_status_t apr_xml_parser_done(apr_xml_parser *parser, |
402 | apr_xml_doc **pdoc) |
403 | { |
404 | char end; |
405 | apr_status_t status = do_parse(parser, &end, 0, 1 /* is_final */); |
406 | |
407 | /* get rid of the parser */ |
408 | (void) apr_pool_cleanup_run(parser->p, parser, cleanup_parser); |
409 | |
410 | if (status) |
411 | return status; |
412 | |
413 | if (pdoc != NULL((void*)0)) |
414 | *pdoc = parser->doc; |
415 | return APR_SUCCESS0; |
416 | } |
417 | |
418 | APU_DECLARE(char *)char * apr_xml_parser_geterror(apr_xml_parser *parser, |
419 | char *errbuf, |
420 | apr_size_t errbufsize) |
421 | { |
422 | int error = parser->error; |
423 | const char *msg; |
424 | |
425 | /* clear our record of an error */ |
426 | parser->error = 0; |
427 | |
428 | switch (error) { |
429 | case 0: |
430 | msg = "No error."; |
431 | break; |
432 | |
433 | case APR_XML_NS_ERROR_UNKNOWN_PREFIX(-1000): |
434 | msg = "An undefined namespace prefix was used."; |
435 | break; |
436 | |
437 | case APR_XML_NS_ERROR_INVALID_DECL(-1001): |
438 | msg = "A namespace prefix was defined with an empty URI."; |
439 | break; |
440 | |
441 | case APR_XML_ERROR_EXPAT1: |
442 | (void) apr_snprintf(errbuf, errbufsize, |
443 | "XML parser error code: %s (%d)", |
444 | XML_ErrorString(parser->xp_err), parser->xp_err); |
445 | return errbuf; |
446 | |
447 | case APR_XML_ERROR_PARSE_DONE2: |
448 | msg = "The parser is not active."; |
449 | break; |
450 | |
451 | default: |
452 | msg = "There was an unknown error within the XML body."; |
453 | break; |
454 | } |
455 | |
456 | (void) apr_cpystrn(errbuf, msg, errbufsize); |
457 | return errbuf; |
458 | } |
459 | |
460 | APU_DECLARE(apr_status_t)apr_status_t apr_xml_parse_file(apr_pool_t *p, |
461 | apr_xml_parser **parser, |
462 | apr_xml_doc **ppdoc, |
463 | apr_file_t *xmlfd, |
464 | apr_size_t buffer_length) |
465 | { |
466 | apr_status_t rv; |
467 | char *buffer; |
468 | apr_size_t length; |
469 | |
470 | *parser = apr_xml_parser_create(p); |
471 | if (*parser == NULL((void*)0)) { |
472 | /* FIXME: returning an error code would be nice, |
473 | * but we dont get one ;( */ |
474 | return APR_EGENERAL(20000 + 14); |
475 | } |
476 | buffer = apr_palloc(p, buffer_length); |
477 | length = buffer_length; |
478 | |
479 | rv = apr_file_read(xmlfd, buffer, &length); |
480 | |
481 | while (rv == APR_SUCCESS0) { |
482 | rv = apr_xml_parser_feed(*parser, buffer, length); |
483 | if (rv != APR_SUCCESS0) { |
484 | return rv; |
485 | } |
486 | |
487 | length = buffer_length; |
488 | rv = apr_file_read(xmlfd, buffer, &length); |
489 | } |
490 | if (rv != APR_EOF((20000 + 50000) + 14)) { |
491 | return rv; |
492 | } |
493 | rv = apr_xml_parser_done(*parser, ppdoc); |
494 | *parser = NULL((void*)0); |
495 | return rv; |
496 | } |
497 | |
498 | APU_DECLARE(void)void apr_text_append(apr_pool_t * p, apr_text_header *hdr, |
499 | const char *text) |
500 | { |
501 | apr_text *t = apr_palloc(p, sizeof(*t)); |
502 | |
503 | t->text = text; |
504 | t->next = NULL((void*)0); |
505 | |
506 | if (hdr->first == NULL((void*)0)) { |
507 | /* no text elements yet */ |
508 | hdr->first = hdr->last = t; |
509 | } |
510 | else { |
511 | /* append to the last text element */ |
512 | hdr->last->next = t; |
513 | hdr->last = t; |
514 | } |
515 | } |
516 | |
517 | |
518 | /* --------------------------------------------------------------- |
519 | ** |
520 | ** XML UTILITY FUNCTIONS |
521 | */ |
522 | |
523 | /* |
524 | ** apr_xml_quote_string: quote an XML string |
525 | ** |
526 | ** Replace '<', '>', and '&' with '<', '>', and '&'. |
527 | ** If quotes is true, then replace '"' with '"'. |
528 | ** |
529 | ** quotes is typically set to true for XML strings that will occur within |
530 | ** double quotes -- attribute values. |
531 | */ |
532 | APU_DECLARE(const char *)const char * apr_xml_quote_string(apr_pool_t *p, const char *s, |
533 | int quotes) |
534 | { |
535 | const char *scan; |
536 | apr_size_t len = 0; |
537 | apr_size_t extra = 0; |
538 | char *qstr; |
539 | char *qscan; |
540 | char c; |
541 | |
542 | for (scan = s; (c = *scan) != '\0'; ++scan, ++len) { |
543 | if (c == '<' || c == '>') |
544 | extra += 3; /* < or > */ |
545 | else if (c == '&') |
546 | extra += 4; /* & */ |
547 | else if (quotes && c == '"') |
548 | extra += 5; /* " */ |
549 | } |
550 | |
551 | /* nothing to do? */ |
552 | if (extra == 0) |
553 | return s; |
554 | |
555 | qstr = apr_palloc(p, len + extra + 1); |
556 | for (scan = s, qscan = qstr; (c = *scan) != '\0'; ++scan) { |
557 | if (c == '<') { |
558 | *qscan++ = '&'; |
559 | *qscan++ = 'l'; |
560 | *qscan++ = 't'; |
561 | *qscan++ = ';'; |
562 | } |
563 | else if (c == '>') { |
564 | *qscan++ = '&'; |
565 | *qscan++ = 'g'; |
566 | *qscan++ = 't'; |
567 | *qscan++ = ';'; |
568 | } |
569 | else if (c == '&') { |
570 | *qscan++ = '&'; |
571 | *qscan++ = 'a'; |
572 | *qscan++ = 'm'; |
573 | *qscan++ = 'p'; |
574 | *qscan++ = ';'; |
575 | } |
576 | else if (quotes && c == '"') { |
577 | *qscan++ = '&'; |
578 | *qscan++ = 'q'; |
579 | *qscan++ = 'u'; |
580 | *qscan++ = 'o'; |
581 | *qscan++ = 't'; |
582 | *qscan++ = ';'; |
583 | } |
584 | else { |
585 | *qscan++ = c; |
586 | } |
587 | } |
588 | |
589 | *qscan = '\0'; |
590 | return qstr; |
591 | } |
592 | |
593 | /* how many characters for the given integer? */ |
594 | #define APR_XML_NS_LEN(ns)((ns) < 10 ? 1 : (ns) < 100 ? 2 : (ns) < 1000 ? 3 : ( ns) < 10000 ? 4 : (ns) < 100000 ? 5 : (ns) < 1000000 ? 6 : (ns) < 10000000 ? 7 : (ns) < 100000000 ? 8 : (ns ) < 1000000000 ? 9 : 10) ((ns) < 10 ? 1 : (ns) < 100 ? 2 : (ns) < 1000 ? 3 : \ |
595 | (ns) < 10000 ? 4 : (ns) < 100000 ? 5 : \ |
596 | (ns) < 1000000 ? 6 : (ns) < 10000000 ? 7 : \ |
597 | (ns) < 100000000 ? 8 : (ns) < 1000000000 ? 9 : 10) |
598 | |
599 | static apr_size_t text_size(const apr_text *t) |
600 | { |
601 | apr_size_t size = 0; |
602 | |
603 | for (; t; t = t->next) |
604 | size += strlen(t->text); |
605 | return size; |
606 | } |
607 | |
608 | static apr_size_t elem_size(const apr_xml_elem *elem, int style, |
609 | apr_array_header_t *namespaces, int *ns_map) |
610 | { |
611 | apr_size_t size; |
612 | |
613 | if (style == APR_XML_X2T_FULL0 || style == APR_XML_X2T_FULL_NS_LANG3) { |
614 | const apr_xml_attr *attr; |
615 | |
616 | size = 0; |
617 | |
618 | if (style == APR_XML_X2T_FULL_NS_LANG3) { |
619 | int i; |
620 | |
621 | /* |
622 | ** The outer element will contain xmlns:ns%d="%s" attributes |
623 | ** and an xml:lang attribute, if applicable. |
624 | */ |
625 | |
626 | for (i = namespaces->nelts; i--;) { |
627 | /* compute size of: ' xmlns:ns%d="%s"' */ |
628 | size += (9 + APR_XML_NS_LEN(i)((i) < 10 ? 1 : (i) < 100 ? 2 : (i) < 1000 ? 3 : (i) < 10000 ? 4 : (i) < 100000 ? 5 : (i) < 1000000 ? 6 : (i) < 10000000 ? 7 : (i) < 100000000 ? 8 : (i) < 1000000000 ? 9 : 10) + 2 + |
629 | strlen(APR_XML_GET_URI_ITEM(namespaces, i)(((const char * const *)(namespaces)->elts)[i])) + 1); |
630 | } |
631 | |
632 | if (elem->lang != NULL((void*)0)) { |
633 | /* compute size of: ' xml:lang="%s"' */ |
634 | size += 11 + strlen(elem->lang) + 1; |
635 | } |
636 | } |
637 | |
638 | if (elem->ns == APR_XML_NS_NONE-10) { |
639 | /* compute size of: <%s> */ |
640 | size += 1 + strlen(elem->name) + 1; |
641 | } |
642 | else { |
643 | int ns = ns_map ? ns_map[elem->ns] : elem->ns; |
644 | |
645 | /* compute size of: <ns%d:%s> */ |
646 | size += 3 + APR_XML_NS_LEN(ns)((ns) < 10 ? 1 : (ns) < 100 ? 2 : (ns) < 1000 ? 3 : ( ns) < 10000 ? 4 : (ns) < 100000 ? 5 : (ns) < 1000000 ? 6 : (ns) < 10000000 ? 7 : (ns) < 100000000 ? 8 : (ns ) < 1000000000 ? 9 : 10) + 1 + strlen(elem->name) + 1; |
647 | } |
648 | |
649 | if (APR_XML_ELEM_IS_EMPTY(elem)((elem)->first_child == ((void*)0) && (elem)->first_cdata .first == ((void*)0))) { |
650 | /* insert a closing "/" */ |
651 | size += 1; |
652 | } |
653 | else { |
654 | /* |
655 | * two of above plus "/": |
656 | * <ns%d:%s> ... </ns%d:%s> |
657 | * OR <%s> ... </%s> |
658 | */ |
659 | size = 2 * size + 1; |
660 | } |
661 | |
662 | for (attr = elem->attr; attr; attr = attr->next) { |
663 | if (attr->ns == APR_XML_NS_NONE-10) { |
664 | /* compute size of: ' %s="%s"' */ |
665 | size += 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1; |
666 | } |
667 | else { |
668 | /* compute size of: ' ns%d:%s="%s"' */ |
669 | size += 3 + APR_XML_NS_LEN(attr->ns)((attr->ns) < 10 ? 1 : (attr->ns) < 100 ? 2 : (attr ->ns) < 1000 ? 3 : (attr->ns) < 10000 ? 4 : (attr ->ns) < 100000 ? 5 : (attr->ns) < 1000000 ? 6 : ( attr->ns) < 10000000 ? 7 : (attr->ns) < 100000000 ? 8 : (attr->ns) < 1000000000 ? 9 : 10) + 1 + strlen(attr->name) + 2 + strlen(attr->value) + 1; |
670 | } |
671 | } |
672 | |
673 | /* |
674 | ** If the element has an xml:lang value that is *different* from |
675 | ** its parent, then add the thing in: ' xml:lang="%s"'. |
676 | ** |
677 | ** NOTE: we take advantage of the pointer equality established by |
678 | ** the parsing for "inheriting" the xml:lang values from parents. |
679 | */ |
680 | if (elem->lang != NULL((void*)0) && |
681 | (elem->parent == NULL((void*)0) || elem->lang != elem->parent->lang)) { |
682 | size += 11 + strlen(elem->lang) + 1; |
683 | } |
684 | } |
685 | else if (style == APR_XML_X2T_LANG_INNER2) { |
686 | /* |
687 | * This style prepends the xml:lang value plus a null terminator. |
688 | * If a lang value is not present, then we insert a null term. |
689 | */ |
690 | size = elem->lang ? strlen(elem->lang) + 1 : 1; |
691 | } |
692 | else |
693 | size = 0; |
694 | |
695 | size += text_size(elem->first_cdata.first); |
696 | |
697 | for (elem = elem->first_child; elem; elem = elem->next) { |
698 | /* the size of the child element plus the CDATA that follows it */ |
699 | size += (elem_size(elem, APR_XML_X2T_FULL0, NULL((void*)0), ns_map) + |
700 | text_size(elem->following_cdata.first)); |
701 | } |
702 | |
703 | return size; |
704 | } |
705 | |
706 | static char *write_text(char *s, const apr_text *t) |
707 | { |
708 | for (; t; t = t->next) { |
709 | apr_size_t len = strlen(t->text); |
710 | memcpy(s, t->text, len); |
711 | s += len; |
712 | } |
713 | return s; |
714 | } |
715 | |
716 | static char *write_elem(char *s, const apr_xml_elem *elem, int style, |
717 | apr_array_header_t *namespaces, int *ns_map) |
718 | { |
719 | const apr_xml_elem *child; |
720 | apr_size_t len; |
721 | int ns; |
722 | |
723 | if (style == APR_XML_X2T_FULL0 || style == APR_XML_X2T_FULL_NS_LANG3) { |
724 | int empty = APR_XML_ELEM_IS_EMPTY(elem)((elem)->first_child == ((void*)0) && (elem)->first_cdata .first == ((void*)0)); |
725 | const apr_xml_attr *attr; |
726 | |
727 | if (elem->ns == APR_XML_NS_NONE-10) { |
728 | len = sprintf(s, "<%s", elem->name); |
729 | } |
730 | else { |
731 | ns = ns_map ? ns_map[elem->ns] : elem->ns; |
732 | len = sprintf(s, "<ns%d:%s", ns, elem->name); |
733 | } |
734 | s += len; |
735 | |
736 | for (attr = elem->attr; attr; attr = attr->next) { |
737 | if (attr->ns == APR_XML_NS_NONE-10) |
738 | len = sprintf(s, " %s=\"%s\"", attr->name, attr->value); |
739 | else |
740 | len = sprintf(s, " ns%d:%s=\"%s\"", attr->ns, attr->name, attr->value); |
741 | s += len; |
742 | } |
743 | |
744 | /* add the xml:lang value if necessary */ |
745 | if (elem->lang != NULL((void*)0) && |
746 | (style == APR_XML_X2T_FULL_NS_LANG3 || |
747 | elem->parent == NULL((void*)0) || |
748 | elem->lang != elem->parent->lang)) { |
749 | len = sprintf(s, " xml:lang=\"%s\"", elem->lang); |
750 | s += len; |
751 | } |
752 | |
753 | /* add namespace definitions, if required */ |
754 | if (style == APR_XML_X2T_FULL_NS_LANG3) { |
755 | int i; |
756 | |
757 | for (i = namespaces->nelts; i--;) { |
758 | len = sprintf(s, " xmlns:ns%d=\"%s\"", i, |
759 | APR_XML_GET_URI_ITEM(namespaces, i)(((const char * const *)(namespaces)->elts)[i])); |
760 | s += len; |
761 | } |
762 | } |
763 | |
764 | /* no more to do. close it up and go. */ |
765 | if (empty) { |
766 | *s++ = '/'; |
767 | *s++ = '>'; |
768 | return s; |
769 | } |
770 | |
771 | /* just close it */ |
772 | *s++ = '>'; |
773 | } |
774 | else if (style == APR_XML_X2T_LANG_INNER2) { |
775 | /* prepend the xml:lang value */ |
776 | if (elem->lang != NULL((void*)0)) { |
777 | len = strlen(elem->lang); |
778 | memcpy(s, elem->lang, len); |
779 | s += len; |
780 | } |
781 | *s++ = '\0'; |
782 | } |
783 | |
784 | s = write_text(s, elem->first_cdata.first); |
785 | |
786 | for (child = elem->first_child; child; child = child->next) { |
787 | s = write_elem(s, child, APR_XML_X2T_FULL0, NULL((void*)0), ns_map); |
788 | s = write_text(s, child->following_cdata.first); |
789 | } |
790 | |
791 | if (style == APR_XML_X2T_FULL0 || style == APR_XML_X2T_FULL_NS_LANG3) { |
792 | if (elem->ns == APR_XML_NS_NONE-10) { |
793 | len = sprintf(s, "</%s>", elem->name); |
794 | } |
795 | else { |
796 | ns = ns_map ? ns_map[elem->ns] : elem->ns; |
797 | len = sprintf(s, "</ns%d:%s>", ns, elem->name); |
798 | } |
799 | s += len; |
800 | } |
801 | |
802 | return s; |
803 | } |
804 | |
805 | APU_DECLARE(void)void apr_xml_quote_elem(apr_pool_t *p, apr_xml_elem *elem) |
806 | { |
807 | apr_text *scan_txt; |
808 | apr_xml_attr *scan_attr; |
809 | apr_xml_elem *scan_elem; |
810 | |
811 | /* convert the element's text */ |
812 | for (scan_txt = elem->first_cdata.first; |
813 | scan_txt != NULL((void*)0); |
814 | scan_txt = scan_txt->next) { |
815 | scan_txt->text = apr_xml_quote_string(p, scan_txt->text, 0); |
816 | } |
817 | for (scan_txt = elem->following_cdata.first; |
818 | scan_txt != NULL((void*)0); |
819 | scan_txt = scan_txt->next) { |
820 | scan_txt->text = apr_xml_quote_string(p, scan_txt->text, 0); |
821 | } |
822 | |
823 | /* convert the attribute values */ |
824 | for (scan_attr = elem->attr; |
825 | scan_attr != NULL((void*)0); |
826 | scan_attr = scan_attr->next) { |
827 | scan_attr->value = apr_xml_quote_string(p, scan_attr->value, 1); |
828 | } |
829 | |
830 | /* convert the child elements */ |
831 | for (scan_elem = elem->first_child; |
832 | scan_elem != NULL((void*)0); |
833 | scan_elem = scan_elem->next) { |
834 | apr_xml_quote_elem(p, scan_elem); |
835 | } |
836 | } |
837 | |
838 | /* convert an element to a text string */ |
839 | APU_DECLARE(void)void apr_xml_to_text(apr_pool_t * p, const apr_xml_elem *elem, |
840 | int style, apr_array_header_t *namespaces, |
841 | int *ns_map, const char **pbuf, |
842 | apr_size_t *psize) |
843 | { |
844 | /* get the exact size, plus a null terminator */ |
845 | apr_size_t size = elem_size(elem, style, namespaces, ns_map) + 1; |
846 | char *s = apr_palloc(p, size); |
847 | |
848 | (void) write_elem(s, elem, style, namespaces, ns_map); |
849 | s[size - 1] = '\0'; |
850 | |
851 | *pbuf = s; |
852 | if (psize) |
853 | *psize = size; |
854 | } |
855 | |
856 | APU_DECLARE(const char *)const char * apr_xml_empty_elem(apr_pool_t * p, |
857 | const apr_xml_elem *elem) |
858 | { |
859 | if (elem->ns == APR_XML_NS_NONE-10) { |
860 | /* |
861 | * The prefix (xml...) is already within the prop name, or |
862 | * the element simply has no prefix. |
863 | */ |
864 | return apr_psprintf(p, "<%s/>" DEBUG_CR"\r\n", elem->name); |
865 | } |
866 | |
867 | return apr_psprintf(p, "<ns%d:%s/>" DEBUG_CR"\r\n", elem->ns, elem->name); |
868 | } |
869 | |
870 | /* return the URI's (existing) index, or insert it and return a new index */ |
871 | APU_DECLARE(int)int apr_xml_insert_uri(apr_array_header_t *uri_array, |
872 | const char *uri) |
873 | { |
874 | int i; |
875 | const char **pelt; |
876 | |
877 | /* never insert an empty URI; this index is always APR_XML_NS_NONE */ |
878 | if (*uri == '\0') |
879 | return APR_XML_NS_NONE-10; |
880 | |
881 | for (i = uri_array->nelts; i--;) { |
882 | if (strcmp(uri, APR_XML_GET_URI_ITEM(uri_array, i))__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (uri) && __builtin_constant_p ((((const char * const *)(uri_array)->elts)[i])) && (__s1_len = __builtin_strlen (uri), __s2_len = __builtin_strlen ((((const char * const *) (uri_array)->elts)[i])), (!((size_t)(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1) || __s1_len >= 4) && (!((size_t)(const void *)(((((const char * const *)(uri_array )->elts)[i])) + 1) - (size_t)(const void *)((((const char * const *)(uri_array)->elts)[i])) == 1) || __s2_len >= 4 )) ? __builtin_strcmp (uri, (((const char * const *)(uri_array )->elts)[i])) : (__builtin_constant_p (uri) && ((size_t )(const void *)((uri) + 1) - (size_t)(const void *)(uri) == 1 ) && (__s1_len = __builtin_strlen (uri), __s1_len < 4) ? (__builtin_constant_p ((((const char * const *)(uri_array )->elts)[i])) && ((size_t)(const void *)(((((const char * const *)(uri_array)->elts)[i])) + 1) - (size_t)(const void *)((((const char * const *)(uri_array)->elts)[i])) == 1) ? __builtin_strcmp (uri, (((const char * const *)(uri_array )->elts)[i])) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ((((const char * const *)(uri_array)->elts)[i])); int __result = (((const unsigned char *) (const char *) (uri))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (uri))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (uri))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (uri))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ((((const char * const *)(uri_array)->elts)[i])) && ((size_t)(const void *)(((((const char * const *)(uri_array) ->elts)[i])) + 1) - (size_t)(const void *)((((const char * const *)(uri_array)->elts)[i])) == 1) && (__s2_len = __builtin_strlen ((((const char * const *)(uri_array)-> elts)[i])), __s2_len < 4) ? (__builtin_constant_p (uri) && ((size_t)(const void *)((uri) + 1) - (size_t)(const void *)( uri) == 1) ? __builtin_strcmp (uri, (((const char * const *)( uri_array)->elts)[i])) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (uri); int __result = (((const unsigned char *) (const char *) ((((const char * const *)(uri_array)->elts)[i])))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ((((const char * const *)(uri_array )->elts)[i])))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ((((const char * const *)(uri_array)->elts)[i]))) [2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ((((const char * const *)(uri_array)->elts)[i])))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (uri, (((const char * const *)(uri_array)->elts)[i]))))); }) == 0) |
883 | return i; |
884 | } |
885 | |
886 | pelt = apr_array_push(uri_array); |
887 | *pelt = uri; /* assume uri is const or in a pool */ |
888 | return uri_array->nelts - 1; |
889 | } |
890 | |
891 | /* convert the element to EBCDIC */ |
892 | #if APR_CHARSET_EBCDIC0 |
893 | static apr_status_t apr_xml_parser_convert_elem(apr_xml_elem *e, |
894 | apr_xlate_t *convset) |
895 | { |
896 | apr_xml_attr *a; |
897 | apr_xml_elem *ec; |
898 | apr_text *t; |
899 | apr_size_t inbytes_left, outbytes_left; |
900 | apr_status_t status; |
901 | |
902 | inbytes_left = outbytes_left = strlen(e->name); |
903 | status = apr_xlate_conv_buffer(convset, e->name, &inbytes_left, (char *) e->name, &outbytes_left); |
904 | if (status) { |
905 | return status; |
906 | } |
907 | |
908 | for (t = e->first_cdata.first; t != NULL((void*)0); t = t->next) { |
909 | inbytes_left = outbytes_left = strlen(t->text); |
910 | status = apr_xlate_conv_buffer(convset, t->text, &inbytes_left, (char *) t->text, &outbytes_left); |
911 | if (status) { |
912 | return status; |
913 | } |
914 | } |
915 | |
916 | for (t = e->following_cdata.first; t != NULL((void*)0); t = t->next) { |
917 | inbytes_left = outbytes_left = strlen(t->text); |
918 | status = apr_xlate_conv_buffer(convset, t->text, &inbytes_left, (char *) t->text, &outbytes_left); |
919 | if (status) { |
920 | return status; |
921 | } |
922 | } |
923 | |
924 | for (a = e->attr; a != NULL((void*)0); a = a->next) { |
925 | inbytes_left = outbytes_left = strlen(a->name); |
926 | status = apr_xlate_conv_buffer(convset, a->name, &inbytes_left, (char *) a->name, &outbytes_left); |
927 | if (status) { |
928 | return status; |
929 | } |
930 | inbytes_left = outbytes_left = strlen(a->value); |
931 | status = apr_xlate_conv_buffer(convset, a->value, &inbytes_left, (char *) a->value, &outbytes_left); |
932 | if (status) { |
933 | return status; |
934 | } |
935 | } |
936 | |
937 | for (ec = e->first_child; ec != NULL((void*)0); ec = ec->next) { |
938 | status = apr_xml_parser_convert_elem(ec, convset); |
939 | if (status) { |
940 | return status; |
941 | } |
942 | } |
943 | return APR_SUCCESS0; |
944 | } |
945 | |
946 | /* convert the whole document to EBCDIC */ |
947 | APU_DECLARE(apr_status_t)apr_status_t apr_xml_parser_convert_doc(apr_pool_t *pool, |
948 | apr_xml_doc *pdoc, |
949 | apr_xlate_t *convset) |
950 | { |
951 | apr_status_t status; |
952 | /* Don't convert the namespaces: they are constant! */ |
953 | if (pdoc->namespaces != NULL((void*)0)) { |
954 | int i; |
955 | apr_array_header_t *namespaces; |
956 | namespaces = apr_array_make(pool, pdoc->namespaces->nelts, sizeof(const char *)); |
957 | if (namespaces == NULL((void*)0)) |
958 | return APR_ENOMEM12; |
959 | for (i = 0; i < pdoc->namespaces->nelts; i++) { |
960 | apr_size_t inbytes_left, outbytes_left; |
961 | char *ptr = (char *) APR_XML_GET_URI_ITEM(pdoc->namespaces, i)(((const char * const *)(pdoc->namespaces)->elts)[i]); |
962 | ptr = apr_pstrdup(pool, ptr); |
963 | if ( ptr == NULL((void*)0)) |
964 | return APR_ENOMEM12; |
965 | inbytes_left = outbytes_left = strlen(ptr); |
966 | status = apr_xlate_conv_buffer(convset, ptr, &inbytes_left, ptr, &outbytes_left); |
967 | if (status) { |
968 | return status; |
969 | } |
970 | apr_xml_insert_uri(namespaces, ptr); |
971 | } |
972 | pdoc->namespaces = namespaces; |
973 | } |
974 | return apr_xml_parser_convert_elem(pdoc->root, convset); |
975 | } |
976 | #endif |