Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_subr/xml.c view on Meta::CPAN
/*** XML character validation ***/
svn_boolean_t
svn_xml_is_xml_safe(const char *data, apr_size_t len)
{
const char *end = data + len;
const char *p;
if (! svn_utf__is_valid(data, len))
return FALSE;
for (p = data; p < end; p++)
{
unsigned char c = *p;
if (svn_ctype_iscntrl(c))
{
if ((c != SVN_CTYPE_ASCII_TAB)
&& (c != SVN_CTYPE_ASCII_LINEFEED)
&& (c != SVN_CTYPE_ASCII_CARRIAGERETURN)
&& (c != SVN_CTYPE_ASCII_DELETE))
return FALSE;
}
}
return TRUE;
}
/*** XML escaping. ***/
/* ### ...?
*
* If *OUTSTR is @c NULL, set *OUTSTR to a new stringbuf allocated
* in POOL, else append to the existing stringbuf there.
*/
static void
xml_escape_cdata(svn_stringbuf_t **outstr,
const char *data,
apr_size_t len,
apr_pool_t *pool)
{
const char *end = data + len;
const char *p = data, *q;
if (*outstr == NULL)
*outstr = svn_stringbuf_create_empty(pool);
while (1)
{
/* Find a character which needs to be quoted and append bytes up
to that point. Strictly speaking, '>' only needs to be
quoted if it follows "]]", but it's easier to quote it all
the time.
So, why are we escaping '\r' here? Well, according to the
XML spec, '\r\n' gets converted to '\n' during XML parsing.
Also, any '\r' not followed by '\n' is converted to '\n'. By
golly, if we say we want to escape a '\r', we want to make
sure it remains a '\r'! */
q = p;
while (q < end && *q != '&' && *q != '<' && *q != '>' && *q != '\r')
q++;
svn_stringbuf_appendbytes(*outstr, p, q - p);
/* We may already be a winner. */
if (q == end)
break;
/* Append the entity reference for the character. */
if (*q == '&')
svn_stringbuf_appendcstr(*outstr, "&");
else if (*q == '<')
svn_stringbuf_appendcstr(*outstr, "<");
else if (*q == '>')
svn_stringbuf_appendcstr(*outstr, ">");
else if (*q == '\r')
svn_stringbuf_appendcstr(*outstr, " ");
p = q + 1;
}
}
/* Essentially the same as xml_escape_cdata, with the addition of
whitespace and quote characters. */
static void
xml_escape_attr(svn_stringbuf_t **outstr,
const char *data,
apr_size_t len,
apr_pool_t *pool)
{
const char *end = data + len;
const char *p = data, *q;
if (*outstr == NULL)
*outstr = svn_stringbuf_create_ensure(len, pool);
while (1)
{
/* Find a character which needs to be quoted and append bytes up
to that point. */
q = p;
while (q < end && *q != '&' && *q != '<' && *q != '>'
&& *q != '"' && *q != '\'' && *q != '\r'
&& *q != '\n' && *q != '\t')
q++;
svn_stringbuf_appendbytes(*outstr, p, q - p);
/* We may already be a winner. */
if (q == end)
break;
/* Append the entity reference for the character. */
if (*q == '&')
svn_stringbuf_appendcstr(*outstr, "&");
else if (*q == '<')
svn_stringbuf_appendcstr(*outstr, "<");
else if (*q == '>')
svn_stringbuf_appendcstr(*outstr, ">");
( run in 0.538 second using v1.01-cache-2.11-cpan-483215c6ad5 )