Subversion
svn_xml.h
Go to the documentation of this file.
1 /**
2  * @copyright
3  * ====================================================================
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements. See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership. The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License. You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied. See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  * ====================================================================
21  * @endcopyright
22  *
23  * @file svn_xml.h
24  * @brief XML code shared by various Subversion libraries.
25  */
26 
27 #ifndef SVN_XML_H
28 #define SVN_XML_H
29 
30 #include <apr.h>
31 #include <apr_pools.h>
32 #include <apr_hash.h>
33 
34 #include "svn_types.h"
35 #include "svn_string.h"
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif /* __cplusplus */
40 
41 /** The namespace all Subversion XML uses. */
42 #define SVN_XML_NAMESPACE "svn:"
43 
44 /** Used as style argument to svn_xml_make_open_tag() and friends. */
46  /** <tag ...> */
48 
49  /** <tag ...>, no cosmetic newline */
51 
52  /** <tag .../> */
54 };
55 
56 ␌
57 
58 /** Determine if a string of character @a data of length @a len is a
59  * safe bet for use with the svn_xml_escape_* functions found in this
60  * header.
61  *
62  * Return @c TRUE if it is, @c FALSE otherwise.
63  *
64  * Essentially, this function exists to determine whether or not
65  * simply running a string of bytes through the Subversion XML escape
66  * routines will produce legitimate XML. It should only be necessary
67  * for data which might contain bytes that cannot be safely encoded
68  * into XML (certain control characters, for example).
69  */
71 svn_xml_is_xml_safe(const char *data,
72  apr_size_t len);
73 
74 /** Create or append in @a *outstr an xml-escaped version of @a string,
75  * suitable for output as character data.
76  *
77  * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
78  * in @a pool, else append to the existing stringbuf there.
79  */
80 void
82  const svn_stringbuf_t *string,
83  apr_pool_t *pool);
84 
85 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is an
86  * @c svn_string_t.
87  */
88 void
90  const svn_string_t *string,
91  apr_pool_t *pool);
92 
93 /** Same as svn_xml_escape_cdata_stringbuf(), but @a string is a
94  * NULL-terminated C string.
95  */
96 void
98  const char *string,
99  apr_pool_t *pool);
100 
101 
102 /** Create or append in @a *outstr an xml-escaped version of @a string,
103  * suitable for output as an attribute value.
104  *
105  * If @a *outstr is @c NULL, set @a *outstr to a new stringbuf allocated
106  * in @a pool, else append to the existing stringbuf there.
107  */
108 void
110  const svn_stringbuf_t *string,
111  apr_pool_t *pool);
112 
113 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is an
114  * @c svn_string_t.
115  */
116 void
118  const svn_string_t *string,
119  apr_pool_t *pool);
120 
121 /** Same as svn_xml_escape_attr_stringbuf(), but @a string is a
122  * NULL-terminated C string.
123  */
124 void
126  const char *string,
127  apr_pool_t *pool);
128 
129 /**
130  * Return UTF-8 string @a string if it contains no characters that are
131  * unrepresentable in XML. Else, return a copy of @a string,
132  * allocated in @a pool, with each unrepresentable character replaced
133  * by "?\uuu", where "uuu" is the three-digit unsigned decimal value
134  * of that character.
135  *
136  * Neither the input nor the output need be valid XML; however, the
137  * output can always be safely XML-escaped.
138  *
139  * @note The current implementation treats all Unicode characters as
140  * representable, except for most ASCII control characters (the
141  * exceptions being CR, LF, and TAB, which are valid in XML). There
142  * may be other UTF-8 characters that are invalid in XML; see
143  * http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=90591
144  * and its thread for details.
145  *
146  * @since New in 1.2.
147  */
148 const char *
149 svn_xml_fuzzy_escape(const char *string,
150  apr_pool_t *pool);
151 
152 
153 /*---------------------------------------------------------------*/
154 ␌
155 /* Generalized Subversion XML Parsing */
156 
157 /** A generalized Subversion XML parser object */
158 typedef struct svn_xml_parser_t svn_xml_parser_t;
159 
160 typedef void (*svn_xml_start_elem)(void *baton,
161  const char *name,
162  const char **atts);
163 
164 typedef void (*svn_xml_end_elem)(void *baton, const char *name);
165 
166 /* data is not NULL-terminated. */
167 typedef void (*svn_xml_char_data)(void *baton,
168  const char *data,
169  apr_size_t len);
170 
171 
172 /** Create a general Subversion XML parser.
173  *
174  * The @c svn_xml_parser_t object itself will be allocated from @a pool,
175  * but some internal structures may be allocated out of pool. Use
176  * svn_xml_free_parser() to free all memory used by the parser.
177  *
178  * @since Since Subversion 1.10 parser will be freed automatically on pool
179  * cleanup or by svn_xml_free_parser() call.
180  */
183  svn_xml_start_elem start_handler,
184  svn_xml_end_elem end_handler,
185  svn_xml_char_data data_handler,
186  apr_pool_t *pool);
187 
188 
189 /** Free a general Subversion XML parser */
190 void
192 
193 
194 
195 /** Push @a len bytes of xml data in @a buf at @a svn_parser.
196  *
197  * If this is the final push, @a is_final must be set.
198  *
199  * An error will be returned if there was a syntax problem in the XML,
200  * or if any of the callbacks set an error using
201  * svn_xml_signal_bailout().
202  *
203  * If an error is returned, the @c svn_xml_parser_t will have been freed
204  * automatically, so the caller should not call svn_xml_free_parser().
205  */
206 svn_error_t *
208  const char *buf,
209  apr_size_t len,
210  svn_boolean_t is_final);
211 
212 
213 
214 /** The way to officially bail out of xml parsing.
215  *
216  * Store @a error in @a svn_parser and set all expat callbacks to @c NULL.
217  */
218 void
220  svn_xml_parser_t *svn_parser);
221 
222 
223 
224 
225 ␌
226 /*** Helpers for dealing with the data Expat gives us. ***/
227 
228 /** Return the value associated with @a name in expat attribute array @a atts,
229  * else return @c NULL.
230  *
231  * (There could never be a @c NULL attribute value in the XML,
232  * although the empty string is possible.)
233  *
234  * @a atts is an array of c-strings: even-numbered indexes are names,
235  * odd-numbers hold values. If all is right, it should end on an
236  * even-numbered index pointing to @c NULL.
237  */
238 const char *
239 svn_xml_get_attr_value(const char *name,
240  const char *const *atts);
241 
242 
243 ␌
244 /* Converting between Expat attribute lists and APR hash tables. */
245 
246 
247 /** Create an attribute hash from @c va_list @a ap.
248  *
249  * The contents of @a ap are alternating <tt>char *</tt> keys and
250  * <tt>char *</tt> vals, terminated by a final @c NULL falling on an
251  * even index (zero-based).
252  */
253 apr_hash_t *
255  apr_pool_t *pool);
256 
257 /** Create a hash that corresponds to Expat xml attribute list @a atts.
258  *
259  * The hash's keys and values are <tt>char *</tt>'s.
260  *
261  * @a atts may be NULL, in which case you just get an empty hash back
262  * (this makes life more convenient for some callers).
263  */
264 apr_hash_t *
265 svn_xml_make_att_hash(const char **atts,
266  apr_pool_t *pool);
267 
268 
269 /** Like svn_xml_make_att_hash(), but takes a hash and preserves any
270  * key/value pairs already in it.
271  */
272 void
274  apr_hash_t *ht,
275  apr_pool_t *pool);
276 
277 /** Like svn_xml_make_att_hash(), but takes a hash and overwrites
278  * key/value pairs already in it that also appear in @a atts.
279  */
280 void
282  apr_hash_t *ht,
283  apr_pool_t *pool);
284 
285 
286 ␌
287 /* Printing XML */
288 
289 /** Create an XML header and return it in @a *str.
290  *
291  * Fully-formed XML documents should start out with a header,
292  * something like <pre>
293  * <?xml version="1.0" encoding="UTF-8"?>
294  * </pre>
295  *
296  * This function returns such a header. @a *str must either be @c NULL, in
297  * which case a new string is created, or it must point to an existing
298  * string to be appended to. @a encoding must either be NULL, in which case
299  * encoding information is omitted from the header, or must be the name of
300  * the encoding of the XML document, such as "UTF-8".
301  *
302  * @since New in 1.7.
303  */
304 void
306  const char *encoding,
307  apr_pool_t *pool);
308 
309 /** Like svn_xml_make_header2(), but does not emit encoding information.
310  *
311  * @deprecated Provided for backward compatibility with the 1.6 API.
312  */
314 void
316  apr_pool_t *pool);
317 
318 
319 /** Store a new xml tag @a tagname in @a *str.
320  *
321  * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
322  * in @a pool, else append to the existing stringbuf there.
323  *
324  * Take the tag's attributes from varargs, a SVN_VA_NULL-terminated list of
325  * alternating <tt>char *</tt> key and <tt>char *</tt> val. Do xml-escaping
326  * on each val.
327  *
328  * @a style is one of the enumerated styles in @c svn_xml_open_tag_style.
329  */
330 void
332  apr_pool_t *pool,
333  enum svn_xml_open_tag_style style,
334  const char *tagname,
336 
337 
338 /** Like svn_xml_make_open_tag(), but takes a @c va_list instead of being
339  * variadic.
340  */
341 void
343  apr_pool_t *pool,
344  enum svn_xml_open_tag_style style,
345  const char *tagname,
346  va_list ap);
347 
348 
349 /** Like svn_xml_make_open_tag(), but takes a hash table of attributes
350  * (<tt>char *</tt> keys mapping to <tt>char *</tt> values).
351  *
352  * You might ask, why not just provide svn_xml_make_tag_atts()?
353  *
354  * The reason is that a hash table is the most natural interface to an
355  * attribute list; the fact that Expat uses <tt>char **</tt> atts instead is
356  * certainly a defensible implementation decision, but since we'd have
357  * to have special code to support such lists throughout Subversion
358  * anyway, we might as well write that code for the natural interface
359  * (hashes) and then convert in the few cases where conversion is
360  * needed. Someday it might even be nice to change expat-lite to work
361  * with apr hashes.
362  *
363  * See conversion functions svn_xml_make_att_hash() and
364  * svn_xml_make_att_hash_overlaying(). Callers should use those to
365  * convert Expat attr lists into hashes when necessary.
366  */
367 void
369  apr_pool_t *pool,
370  enum svn_xml_open_tag_style style,
371  const char *tagname,
372  apr_hash_t *attributes);
373 
374 
375 /** Store an xml close tag @a tagname in @a str.
376  *
377  * If @a *str is @c NULL, set @a *str to a new stringbuf allocated
378  * in @a pool, else append to the existing stringbuf there.
379  */
380 void
382  apr_pool_t *pool,
383  const char *tagname);
384 
385 
386 #ifdef __cplusplus
387 }
388 #endif /* __cplusplus */
389 
390 #endif /* SVN_XML_H */
Subversion error object.
Definition: svn_types.h:177
A simple counted string.
Definition: svn_string.h:97
A buffered string, capable of appending without an allocation and copy for each append.
Definition: svn_string.h:105
Counted-length strings for Subversion, plus some C string goodies.
Subversion's data types.
int svn_boolean_t
YABT: Yet Another Boolean Type.
Definition: svn_types.h:137
#define SVN_NEEDS_SENTINEL_NULL
Macro used to mark functions that require a final null sentinel argument.
Definition: svn_types.h:109
#define SVN_DEPRECATED
Macro used to mark deprecated functions.
Definition: svn_types.h:62
struct svn_xml_parser_t svn_xml_parser_t
A generalized Subversion XML parser object.
Definition: svn_xml.h:158
void svn_xml_hash_atts_preserving(const char **atts, apr_hash_t *ht, apr_pool_t *pool)
Like svn_xml_make_att_hash(), but takes a hash and preserves any key/value pairs already in it.
void svn_xml_escape_attr_string(svn_stringbuf_t **outstr, const svn_string_t *string, apr_pool_t *pool)
Same as svn_xml_escape_attr_stringbuf(), but string is an svn_string_t.
apr_hash_t * svn_xml_ap_to_hash(va_list ap, apr_pool_t *pool)
Create an attribute hash from va_list ap.
svn_xml_parser_t * svn_xml_make_parser(void *baton, svn_xml_start_elem start_handler, svn_xml_end_elem end_handler, svn_xml_char_data data_handler, apr_pool_t *pool)
Create a general Subversion XML parser.
void svn_xml_escape_cdata_string(svn_stringbuf_t **outstr, const svn_string_t *string, apr_pool_t *pool)
Same as svn_xml_escape_cdata_stringbuf(), but string is an svn_string_t.
void svn_xml_make_open_tag_hash(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname, apr_hash_t *attributes)
Like svn_xml_make_open_tag(), but takes a hash table of attributes (char * keys mapping to char * val...
void svn_xml_hash_atts_overlaying(const char **atts, apr_hash_t *ht, apr_pool_t *pool)
Like svn_xml_make_att_hash(), but takes a hash and overwrites key/value pairs already in it that also...
apr_hash_t * svn_xml_make_att_hash(const char **atts, apr_pool_t *pool)
Create a hash that corresponds to Expat xml attribute list atts.
svn_boolean_t svn_xml_is_xml_safe(const char *data, apr_size_t len)
Determine if a string of character data of length len is a safe bet for use with the svn_xml_escape_*...
svn_error_t * svn_xml_parse(svn_xml_parser_t *svn_parser, const char *buf, apr_size_t len, svn_boolean_t is_final)
Push len bytes of xml data in buf at svn_parser.
void svn_xml_escape_cdata_cstring(svn_stringbuf_t **outstr, const char *string, apr_pool_t *pool)
Same as svn_xml_escape_cdata_stringbuf(), but string is a NULL-terminated C string.
void svn_xml_escape_cdata_stringbuf(svn_stringbuf_t **outstr, const svn_stringbuf_t *string, apr_pool_t *pool)
Create or append in *outstr an xml-escaped version of string, suitable for output as character data.
void svn_xml_make_close_tag(svn_stringbuf_t **str, apr_pool_t *pool, const char *tagname)
Store an xml close tag tagname in str.
void svn_xml_make_header(svn_stringbuf_t **str, apr_pool_t *pool)
Like svn_xml_make_header2(), but does not emit encoding information.
void svn_xml_free_parser(svn_xml_parser_t *svn_parser)
Free a general Subversion XML parser.
void svn_xml_make_open_tag(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname,...)
Store a new xml tag tagname in *str.
svn_xml_open_tag_style
Used as style argument to svn_xml_make_open_tag() and friends.
Definition: svn_xml.h:45
@ svn_xml_protect_pcdata
<tag ...>, no cosmetic newline
Definition: svn_xml.h:50
@ svn_xml_normal
<tag ...>
Definition: svn_xml.h:47
@ svn_xml_self_closing
<tag .../>
Definition: svn_xml.h:53
void svn_xml_make_open_tag_v(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname, va_list ap)
Like svn_xml_make_open_tag(), but takes a va_list instead of being variadic.
const char * svn_xml_fuzzy_escape(const char *string, apr_pool_t *pool)
Return UTF-8 string string if it contains no characters that are unrepresentable in XML.
void svn_xml_signal_bailout(svn_error_t *error, svn_xml_parser_t *svn_parser)
The way to officially bail out of xml parsing.
void svn_xml_make_header2(svn_stringbuf_t **str, const char *encoding, apr_pool_t *pool)
Create an XML header and return it in *str.
void svn_xml_escape_attr_stringbuf(svn_stringbuf_t **outstr, const svn_stringbuf_t *string, apr_pool_t *pool)
Create or append in *outstr an xml-escaped version of string, suitable for output as an attribute val...
const char * svn_xml_get_attr_value(const char *name, const char *const *atts)
Return the value associated with name in expat attribute array atts, else return NULL.
void svn_xml_escape_attr_cstring(svn_stringbuf_t **outstr, const char *string, apr_pool_t *pool)
Same as svn_xml_escape_attr_stringbuf(), but string is a NULL-terminated C string.