Index: subversion/include/svn_xml.h
===================================================================
--- subversion/include/svn_xml.h (revision 4679)
+++ subversion/include/svn_xml.h (working copy)
@@ -61,27 +61,53 @@
/** Create or append in @a *outstr an xml-escaped version of @a string.
*
* Create or append in @a *outstr an xml-escaped version of @a string,
- * suitable for output as character data or as an attribute value.
+ * suitable for output as character data.
* If @a *outstr is @c NULL, store a new stringbuf, else append to the
* existing stringbuf there.
*/
-void svn_xml_escape_stringbuf (svn_stringbuf_t **outstr,
- const svn_stringbuf_t *string,
- apr_pool_t *pool);
-
-/** Same as @c svn_xml_escape_stringbuf, but @a string is an @c svn_string_t.
- */
-void svn_xml_escape_string (svn_stringbuf_t **outstr,
- const svn_string_t *string,
- apr_pool_t *pool);
-
-/** Same as @c svn_xml_escape_stringbuf, but @a string is a null-terminated
- * C string.
- */
-void svn_xml_escape_cstring (svn_stringbuf_t **outstr,
- const char *string,
- apr_pool_t *pool);
+void svn_xml_escape_cdata_stringbuf (svn_stringbuf_t **outstr,
+ const svn_stringbuf_t *string,
+ apr_pool_t *pool);
+
+/** Same as @c svn_xml_escape_cdata_stringbuf, but @a string is an
+ * @c svn_string_t.
+ */
+void svn_xml_escape_cdata_string (svn_stringbuf_t **outstr,
+ const svn_string_t *string,
+ apr_pool_t *pool);
+/** Same as @c svn_xml_escape_cdata_stringbuf, but @a string is a
+ * null-terminated C string.
+ */
+void svn_xml_escape_cdata_cstring (svn_stringbuf_t **outstr,
+ const char *string,
+ apr_pool_t *pool);
+
+
+/** Create or append in @a *outstr an xml-escaped version of @a string.
+ *
+ * Create or append in @a *outstr an xml-escaped version of @a string,
+ * suitable for output as an attribute value.
+ * If @a *outstr is @c NULL, store a new stringbuf, else append to the
+ * existing stringbuf there.
+ */
+void svn_xml_escape_attr_stringbuf (svn_stringbuf_t **outstr,
+ const svn_stringbuf_t *string,
+ apr_pool_t *pool);
+
+/** Same as @c svn_xml_escape_attr_stringbuf, but @a string is an
+ * @c svn_string_t.
+ */
+void svn_xml_escape_attr_string (svn_stringbuf_t **outstr,
+ const svn_string_t *string,
+ apr_pool_t *pool);
+
+/** Same as @c svn_xml_escape_attr_stringbuf, but @a string is a
+ * null-terminated C string.
+ */
+void svn_xml_escape_attr_cstring (svn_stringbuf_t **outstr,
+ const char *string,
+ apr_pool_t *pool);
/*---------------------------------------------------------------*/
Index: subversion/libsvn_subr/xml.c
===================================================================
--- subversion/libsvn_subr/xml.c (revision 4679)
+++ subversion/libsvn_subr/xml.c (working copy)
@@ -29,10 +29,10 @@
/*** XML escaping. ***/
static void
-xml_escape (svn_stringbuf_t **outstr,
- const char *data,
- apr_size_t len,
- apr_pool_t *pool)
+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;
@@ -47,8 +47,48 @@
quoted if it follows "]]", but it's easier to quote it all
the time. */
q = p;
+ while (q < end && *q != '&' && *q != '<' && *q != '>')
+ 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, ">");
+
+ 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 ("", 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 != '"' && *q != '\'' && *q != '\r'
+ && *q != '\n' && *q != '\t')
q++;
svn_stringbuf_appendbytes (*outstr, p, q - p);
@@ -67,6 +107,12 @@
svn_stringbuf_appendcstr (*outstr, """);
else if (*q == '\'')
svn_stringbuf_appendcstr (*outstr, "'");
+ else if (*q == '\r')
+ svn_stringbuf_appendcstr (*outstr, "
");
+ else if (*q == '\n')
+ svn_stringbuf_appendcstr (*outstr, "
");
+ else if (*q == '\t')
+ svn_stringbuf_appendcstr (*outstr, " ");
p = q + 1;
}
@@ -74,29 +120,56 @@
void
-svn_xml_escape_stringbuf (svn_stringbuf_t **outstr,
- const svn_stringbuf_t *string,
- apr_pool_t *pool)
+svn_xml_escape_cdata_stringbuf (svn_stringbuf_t **outstr,
+ const svn_stringbuf_t *string,
+ apr_pool_t *pool)
+{
+ xml_escape_cdata (outstr, string->data, string->len, pool);
+}
+
+
+void
+svn_xml_escape_cdata_string (svn_stringbuf_t **outstr,
+ const svn_string_t *string,
+ apr_pool_t *pool)
+{
+ xml_escape_cdata (outstr, string->data, string->len, pool);
+}
+
+
+void
+svn_xml_escape_cdata_cstring (svn_stringbuf_t **outstr,
+ const char *string,
+ apr_pool_t *pool)
+{
+ xml_escape_cdata (outstr, string, (apr_size_t) strlen (string), pool);
+}
+
+
+void
+svn_xml_escape_attr_stringbuf (svn_stringbuf_t **outstr,
+ const svn_stringbuf_t *string,
+ apr_pool_t *pool)
{
- xml_escape (outstr, string->data, string->len, pool);
+ xml_escape_attr (outstr, string->data, string->len, pool);
}
void
-svn_xml_escape_string (svn_stringbuf_t **outstr,
- const svn_string_t *string,
- apr_pool_t *pool)
+svn_xml_escape_attr_string (svn_stringbuf_t **outstr,
+ const svn_string_t *string,
+ apr_pool_t *pool)
{
- xml_escape (outstr, string->data, string->len, pool);
+ xml_escape_attr (outstr, string->data, string->len, pool);
}
void
-svn_xml_escape_cstring (svn_stringbuf_t **outstr,
- const char *string,
- apr_pool_t *pool)
+svn_xml_escape_attr_cstring (svn_stringbuf_t **outstr,
+ const char *string,
+ apr_pool_t *pool)
{
- xml_escape (outstr, string, (apr_size_t) strlen (string), pool);
+ xml_escape_attr (outstr, string, (apr_size_t) strlen (string), pool);
}
@@ -339,7 +412,7 @@
svn_stringbuf_appendcstr (*str, "\n ");
svn_stringbuf_appendcstr (*str, key);
svn_stringbuf_appendcstr (*str, "=\"");
- svn_xml_escape_cstring (str, val, pool);
+ svn_xml_escape_attr_cstring (str, val, pool);
svn_stringbuf_appendcstr (*str, "\"");
}
Index: subversion/mod_dav_svn/deadprops.c
===================================================================
--- subversion/mod_dav_svn/deadprops.c (revision 4679)
+++ subversion/mod_dav_svn/deadprops.c (working copy)
@@ -261,7 +261,7 @@
return NULL;
/* XML-escape our properties before sending them across the wire. */
- svn_xml_escape_string(&xmlsafe, propval, db->resource->pool);
+ svn_xml_escape_cdata_string(&xmlsafe, propval, db->resource->pool);
#ifdef SVN_DAV_FEATURE_USE_OLD_NAMESPACES
if (strcmp(name->ns, SVN_PROP_CUSTOM_PREFIX) == 0)
Index: subversion/clients/cmdline/log-cmd.c
===================================================================
--- subversion/clients/cmdline/log-cmd.c (revision 4679)
+++ subversion/clients/cmdline/log-cmd.c (working copy)
@@ -345,7 +345,7 @@
/* xxx */
svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "author",
NULL);
- svn_xml_escape_cstring (&sb, author, pool);
+ svn_xml_escape_cdata_cstring (&sb, author, pool);
svn_xml_make_close_tag (&sb, pool, "author");
if (date == NULL)
@@ -355,7 +355,7 @@
/* xxx */
svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "date",
NULL);
- svn_xml_escape_cstring (&sb, date, pool);
+ svn_xml_escape_cdata_cstring (&sb, date, pool);
svn_xml_make_close_tag (&sb, pool, "date");
if (changed_paths)
@@ -385,7 +385,8 @@
{
/* copyfrom_path, pool);
+ svn_xml_escape_attr_cstring (&escpath,
+ log_item->copyfrom_path, pool);
revstr = apr_psprintf (pool, "%" SVN_REVNUM_T_FMT,
log_item->copyfrom_rev);
svn_xml_make_open_tag (&sb, pool, svn_xml_protect_pcdata, "path",
@@ -400,7 +401,7 @@
"action", action, NULL);
}
/* xxx */
- svn_xml_escape_cstring (&sb, path, pool);
+ svn_xml_escape_cdata_cstring (&sb, path, pool);
svn_xml_make_close_tag (&sb, pool, "path");
}
@@ -419,7 +420,7 @@
NULL, /* no keywords */
FALSE, /* no expansion */
pool));
- svn_xml_escape_cstring (&sb, msg_native_eol, pool);
+ svn_xml_escape_cdata_cstring (&sb, msg_native_eol, pool);
svn_xml_make_close_tag (&sb, pool, "msg");
/* */
Index: subversion/libsvn_ra_dav/commit.c
===================================================================
--- subversion/libsvn_ra_dav/commit.c (revision 4679)
+++ subversion/libsvn_ra_dav/commit.c (working copy)
@@ -515,7 +515,7 @@
if (r->prop_changes == NULL)
r->prop_changes = apr_table_make(pool, 5);
- svn_xml_escape_string(&escaped, value, pool);
+ svn_xml_escape_cdata_string(&escaped, value, pool);
apr_table_set(r->prop_changes, name, escaped->data);
}
else
@@ -1257,7 +1257,7 @@
/* XML-Escape the log message. */
xml_data = NULL; /* Required by svn_xml_escape_*. */
- svn_xml_escape_cstring(&xml_data, log_msg, cc->ras->pool);
+ svn_xml_escape_cdata_cstring(&xml_data, log_msg, cc->ras->pool);
po[0].name = &log_message_prop;
po[0].type = ne_propset;
Index: subversion/libsvn_ra_dav/fetch.c
===================================================================
--- subversion/libsvn_ra_dav/fetch.c (revision 4679)
+++ subversion/libsvn_ra_dav/fetch.c (working copy)
@@ -2232,7 +2232,7 @@
const char *entry;
svn_stringbuf_t *qpath = NULL;
- svn_xml_escape_cstring (&qpath, path, pool);
+ svn_xml_escape_cdata_cstring (&qpath, path, pool);
entry = apr_psprintf(pool,
"%s" DEBUG_CR,
@@ -2302,7 +2302,7 @@
const char *s;
svn_stringbuf_t *qpath = NULL;
- svn_xml_escape_cstring (&qpath, path, pool);
+ svn_xml_escape_cdata_cstring (&qpath, path, pool);
s = apr_psprintf(pool,
"%s" DEBUG_CR,
qpath->data);
@@ -2504,7 +2504,7 @@
if (dst_path)
{
svn_stringbuf_t *dst_path_str = NULL;
- svn_xml_escape_cstring (&dst_path_str, dst_path, ras->pool);
+ svn_xml_escape_cdata_cstring (&dst_path_str, dst_path, ras->pool);
s = apr_psprintf(ras->pool, "%s",
dst_path_str->data);