Author: hwright
Date: Wed Jan 11 15:57:13 2012
New Revision: 1230112
URL: http://svn.apache.org/viewvc?rev=1230112&view=rev
Log:
Merge r1215260, r1215288, r1215374, r1215375, r1215379, r1227146 from trunk:
* r1215260, r1215288, r1215374, r1215375, r1215379, r1227146
Fix issue #4082 ("'svn log --with-all-revprops' over ra-dav
intolerant of XML-unsafe property values").
Justification:
'Tis better to succeed than to fail. Unless of course you're
talking about successfully doing evil, in which case 'tis better
to fail. But we're not talking about doing evil here. Unless
you think XML is evil. But seriously, these commits introduce a
protocol change for WebDAV. I suspect that might disqualify it
in some folks' eyes from backport to a patch release rather
automatically. But the protocol change is (as all our other
protocol changes are) designed to maintain compatibility across
client and server versions. If the client advertises support for
the new behavior, and the server has such support, the bugfix
logic is activitated. A patched client will not trouble an
unpatched server; nor vice-versa. Further, the effects of the
corrected behavior do not persist, so there's no dataset damage
imposed for users who would roll this change back out of their
systems (by reverting to a prior release). Therefore, cmpilato
can't think of a good reason not to backport the change.
Notes:
r1215260 - mod_dav_svn support for this issue
r1215288 - libsvn_ra_neon support for this issue
r1215374 - followup to r1215288
r1215375 - libsvn_ra_serf support for this issue
r1215379 - followup to r1215375
r1227146 - fix unitialised variable
Votes:
+1: philip, cmpilato, rhuijben
Modified:
subversion/branches/1.7.x/ (props changed)
subversion/branches/1.7.x/STATUS
subversion/branches/1.7.x/subversion/libsvn_ra_neon/log.c
subversion/branches/1.7.x/subversion/libsvn_ra_serf/log.c
subversion/branches/1.7.x/subversion/mod_dav_svn/reports/log.c
Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jan 11 15:57:13 2012
@@ -70,4 +70,4 @@
/subversion/branches/tree-conflicts:868291-873154
/subversion/branches/tree-conflicts-notify:873926-874008
/subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148652,1148662,1148699,1148853,1148877,1148882,1148936,1149103,1149105,1149135,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151854,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153540,1153566,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154278,1154379,1154382,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,115
6098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,1156827,1156838,1157416,1158187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163243,1163383,1163557,1163792,1163953,1164027,1164386,1164426,1164517,1164535,1164554,1164580,1164614,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1167681,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174761,1174797-1174798,1174806,1175888,1176915,1176949,1177001,1177492,1177732,1178280,1178282,1178942,1179680,1179767,1180154,1181090,
1181110,1181155,1181215,1181609,1181666,1182115,1182527,1182771,1182904,1182909,1183054,1183263,1183347,1185222,1185242,1185280,1185282,1185730,1185738,1185746,1185763,1185768,1185886,1185911,1185918,1186059,1186092,1186101,1186107,1186109,1186121,1186231,1186240,1186422,1186434,1186732,1186755,1186784,1186815,1186928,1186944,1186981,1186983,1187311,1187676,1187695,1188609,1188652,1188677,1188762,1188774,1189190,1189261,1189395,1189580,1189665,1195480,1197135,1197998,1199876,1199950,1200837,1201002,1201824,1202135,1202187,1202630,1202807,1203546,1203651,1203653,1204167,1204478,1204610,1204673,1205193,1205726,1205839,1205848,1206523,1206533,1207858,1207949,1208840,1209631,1209654,1210195,1211483,1211859,1211885,1212476,1212482,1212484,1213331,1213673,1213681,1213690,1213711,1213716,1214139,1220742,1220750,1221793,1222521,1222693,1229252
+/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148652,1148662,1148699,1148853,1148877,1148882,1148936,1149103,1149105,1149135,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151854,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153540,1153566,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154278,1154379,1154382,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,115
6098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,1156827,1156838,1157416,1158187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163243,1163383,1163557,1163792,1163953,1164027,1164386,1164426,1164517,1164535,1164554,1164580,1164614,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1167681,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174761,1174797-1174798,1174806,1175888,1176915,1176949,1177001,1177492,1177732,1178280,1178282,1178942,1179680,1179767,1180154,1181090,
1181110,1181155,1181215,1181609,1181666,1182115,1182527,1182771,1182904,1182909,1183054,1183263,1183347,1185222,1185242,1185280,1185282,1185730,1185738,1185746,1185763,1185768,1185886,1185911,1185918,1186059,1186092,1186101,1186107,1186109,1186121,1186231,1186240,1186422,1186434,1186732,1186755,1186784,1186815,1186928,1186944,1186981,1186983,1187311,1187676,1187695,1188609,1188652,1188677,1188762,1188774,1189190,1189261,1189395,1189580,1189665,1195480,1197135,1197998,1199876,1199950,1200837,1201002,1201824,1202135,1202187,1202630,1202807,1203546,1203651,1203653,1204167,1204478,1204610,1204673,1205193,1205726,1205839,1205848,1206523,1206533,1207858,1207949,1208840,1209631,1209654,1210195,1211483,1211859,1211885,1212476,1212482,1212484,1213331,1213673,1213681,1213690,1213711,1213716,1214139,1215260,1215288,1215374-1215375,1215379,1220742,1220750,1221793,1222521,1222693,1227146,1229252
Modified: subversion/branches/1.7.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1230112&r1=1230111&r2=1230112&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Wed Jan 11 15:57:13 2012
@@ -187,33 +187,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1215260, r1215288, r1215374, r1215375, r1215379, r1227146
- Fix issue #4082 ("'svn log --with-all-revprops' over ra-dav
- intolerant of XML-unsafe property values").
- Justification:
- 'Tis better to succeed than to fail. Unless of course you're
- talking about successfully doing evil, in which case 'tis better
- to fail. But we're not talking about doing evil here. Unless
- you think XML is evil. But seriously, these commits introduce a
- protocol change for WebDAV. I suspect that might disqualify it
- in some folks' eyes from backport to a patch release rather
- automatically. But the protocol change is (as all our other
- protocol changes are) designed to maintain compatibility across
- client and server versions. If the client advertises support for
- the new behavior, and the server has such support, the bugfix
- logic is activitated. A patched client will not trouble an
- unpatched server; nor vice-versa. Further, the effects of the
- corrected behavior do not persist, so there's no dataset damage
- imposed for users who would roll this change back out of their
- systems (by reverting to a prior release). Therefore, cmpilato
- can't think of a good reason not to backport the change.
- Notes:
- r1215260 - mod_dav_svn support for this issue
- r1215288 - libsvn_ra_neon support for this issue
- r1215374 - followup to r1215288
- r1215375 - libsvn_ra_serf support for this issue
- r1215379 - followup to r1215375
- r1227146 - fix unitialised variable
- Votes:
- +1: philip, cmpilato, rhuijben
Modified: subversion/branches/1.7.x/subversion/libsvn_ra_neon/log.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_ra_neon/log.c?rev=1230112&r1=1230111&r2=1230112&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_ra_neon/log.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_ra_neon/log.c Wed Jan 11
15:57:13 2012
@@ -32,6 +32,7 @@
#include "svn_error.h"
#include "svn_pools.h"
#include "svn_path.h"
+#include "svn_base64.h"
#include "svn_xml.h"
#include "svn_props.h"
@@ -52,6 +53,8 @@ struct log_baton
*/
svn_stringbuf_t *want_cdata;
svn_stringbuf_t *cdata;
+ const char *cdata_encoding; /* encoding of CDATA (NULL or "base64") */
+
/* Allocate log message information.
* NOTE: this pool may be cleared multiple times as log messages are
* received.
@@ -162,14 +165,27 @@ log_start_element(int *elem, void *baton
case ELEM_comment:
lb->want_cdata = lb->cdata;
svn_stringbuf_setempty(lb->cdata);
+ lb->cdata_encoding = NULL;
+
+ /* Some tags might contain encoded CDATA. */
+ if ((elm->id == ELEM_comment) ||
+ (elm->id == ELEM_creator_displayname) ||
+ (elm->id == ELEM_log_date) ||
+ (elm->id == ELEM_rev_prop))
+ {
+ lb->cdata_encoding = svn_xml_get_attr_value("encoding", atts);
+ if (lb->cdata_encoding)
+ lb->cdata_encoding = apr_pstrdup(lb->subpool, lb->cdata_encoding);
+ }
+
+ /* revprop tags have names. */
if (elm->id == ELEM_revprop)
{
- lb->revprop_name = apr_pstrdup(lb->subpool,
- svn_xml_get_attr_value("name",
- atts));
- if (lb->revprop_name == NULL)
+ const char *revprop_name = svn_xml_get_attr_value("name", atts);
+ if (revprop_name == NULL)
return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
_("Missing name attr in revprop
element"));
+ lb->revprop_name = apr_pstrdup(lb->subpool, revprop_name);
}
break;
case ELEM_has_children:
@@ -235,6 +251,36 @@ log_start_element(int *elem, void *baton
return SVN_NO_ERROR;
}
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in LB,
+ * decoded as necessary, and allocated from LB->subpool.
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+ struct log_baton *lb)
+{
+ if (lb->cdata_encoding)
+ {
+ svn_string_t in;
+ in.data = lb->cdata->data;
+ in.len = lb->cdata->len;
+
+ /* Check for a known encoding type. This is easy -- there's
+ only one. */
+ if (strcmp(lb->cdata_encoding, "base64") != 0)
+ return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+
+ *decoded_cdata = svn_base64_decode_string(&in, lb->subpool);
+ }
+ else
+ {
+ *decoded_cdata = svn_string_create_from_buf(lb->cdata, lb->subpool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
/*
* This implements the `svn_ra_neon__xml_endelm_cb' prototype.
@@ -244,6 +290,10 @@ log_end_element(void *baton, int state,
const char *nspace, const char *name)
{
struct log_baton *lb = baton;
+ const svn_string_t *decoded_cdata;
+
+ if (lb->want_cdata)
+ SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, lb));
switch (state)
{
@@ -256,8 +306,7 @@ log_end_element(void *baton, int state,
if (! lb->log_entry->revprops)
lb->log_entry->revprops = apr_hash_make(lb->subpool);
apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
- APR_HASH_KEY_STRING,
- svn_string_create_from_buf(lb->cdata, lb->subpool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
break;
case ELEM_log_date:
@@ -266,8 +315,7 @@ log_end_element(void *baton, int state,
if (! lb->log_entry->revprops)
lb->log_entry->revprops = apr_hash_make(lb->subpool);
apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_DATE,
- APR_HASH_KEY_STRING,
- svn_string_create_from_buf(lb->cdata, lb->subpool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
break;
case ELEM_added_path:
@@ -289,8 +337,7 @@ log_end_element(void *baton, int state,
if (! lb->log_entry->revprops)
lb->log_entry->revprops = apr_hash_make(lb->subpool);
apr_hash_set(lb->log_entry->revprops, lb->revprop_name,
- APR_HASH_KEY_STRING,
- svn_string_create_from_buf(lb->cdata, lb->subpool));
+ APR_HASH_KEY_STRING, decoded_cdata);
break;
case ELEM_comment:
if (lb->want_message)
@@ -298,8 +345,7 @@ log_end_element(void *baton, int state,
if (! lb->log_entry->revprops)
lb->log_entry->revprops = apr_hash_make(lb->subpool);
apr_hash_set(lb->log_entry->revprops, SVN_PROP_REVISION_LOG,
- APR_HASH_KEY_STRING,
- svn_string_create_from_buf(lb->cdata, lb->subpool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
break;
case ELEM_log_item:
@@ -380,8 +426,8 @@ svn_error_t * svn_ra_neon__get_log(svn_r
Maybe Greg can explain? Meanwhile, I'm tentatively using
"request_*" for my local vars below. */
- static const char log_request_head[]
- = "<S:log-report xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR;
+ static const char log_request_head[] = "<S:log-report xmlns:S=\""
+ SVN_XML_NAMESPACE "\">" DEBUG_CR "<S:encode-binary-props/>";
static const char log_request_tail[] = "</S:log-report>" DEBUG_CR;
@@ -494,6 +540,7 @@ svn_error_t * svn_ra_neon__get_log(svn_r
lb.cdata = svn_stringbuf_create("", pool);
lb.log_entry = svn_log_entry_create(pool);
lb.want_cdata = NULL;
+ lb.cdata_encoding = NULL;
reset_log_item(&lb);
/* ras's URL may not exist in HEAD, and thus it's not safe to send
Modified: subversion/branches/1.7.x/subversion/libsvn_ra_serf/log.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_ra_serf/log.c?rev=1230112&r1=1230111&r2=1230112&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_ra_serf/log.c Wed Jan 11
15:57:13 2012
@@ -32,6 +32,7 @@
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_dav.h"
+#include "svn_base64.h"
#include "svn_xml.h"
#include "svn_config.h"
#include "svn_path.h"
@@ -67,9 +68,12 @@ typedef enum log_state_e {
typedef struct log_info_t {
apr_pool_t *pool;
- /* The currently collected value as we build it up */
+ /* The currently collected value as we build it up, and its wire
+ * encoding (if any).
+ */
const char *tmp;
apr_size_t tmp_len;
+ const char *tmp_encoding;
/* Temporary change path - ultimately inserted into changed_paths hash. */
svn_log_changed_path2_t *tmp_path;
@@ -114,7 +118,8 @@ typedef struct log_context_t {
static log_info_t *
push_state(svn_ra_serf__xml_parser_t *parser,
log_context_t *log_ctx,
- log_state_e state)
+ log_state_e state,
+ const char **attrs)
{
svn_ra_serf__xml_push_state(parser, state);
@@ -152,6 +157,10 @@ push_state(svn_ra_serf__xml_parser_t *pa
{
log_info_t *info = parser->state->private;
+ info->tmp_encoding = svn_xml_get_attr_value("encoding", attrs);
+ if (info->tmp_encoding)
+ info->tmp_encoding = apr_pstrdup(info->pool, info->tmp_encoding);
+
if (!info->log_entry->revprops)
{
info->log_entry->revprops = apr_hash_make(info->pool);
@@ -192,12 +201,12 @@ start_log(svn_ra_serf__xml_parser_t *par
if (state == NONE &&
strcmp(name.name, "log-report") == 0)
{
- push_state(parser, log_ctx, REPORT);
+ push_state(parser, log_ctx, REPORT, attrs);
}
else if (state == REPORT &&
strcmp(name.name, "log-item") == 0)
{
- push_state(parser, log_ctx, ITEM);
+ push_state(parser, log_ctx, ITEM, attrs);
}
else if (state == ITEM)
{
@@ -205,44 +214,43 @@ start_log(svn_ra_serf__xml_parser_t *par
if (strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
{
- push_state(parser, log_ctx, VERSION);
+ push_state(parser, log_ctx, VERSION, attrs);
}
else if (strcmp(name.name, "creator-displayname") == 0)
{
- push_state(parser, log_ctx, CREATOR);
+ info = push_state(parser, log_ctx, CREATOR, attrs);
}
else if (strcmp(name.name, "date") == 0)
{
- push_state(parser, log_ctx, DATE);
+ info = push_state(parser, log_ctx, DATE, attrs);
}
else if (strcmp(name.name, "comment") == 0)
{
- push_state(parser, log_ctx, COMMENT);
+ info = push_state(parser, log_ctx, COMMENT, attrs);
}
else if (strcmp(name.name, "revprop") == 0)
{
- const char *revprop_name;
- info = push_state(parser, log_ctx, REVPROP);
- revprop_name = svn_xml_get_attr_value("name", attrs);
+ const char *revprop_name =
+ svn_xml_get_attr_value("name", attrs);
if (revprop_name == NULL)
return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
_("Missing name attr in revprop
element"));
-
+ info = push_state(parser, log_ctx, REVPROP, attrs);
info->revprop_name = apr_pstrdup(info->pool, revprop_name);
}
else if (strcmp(name.name, "has-children") == 0)
{
- push_state(parser, log_ctx, HAS_CHILDREN);
+ push_state(parser, log_ctx, HAS_CHILDREN, attrs);
}
else if (strcmp(name.name, "subtractive-merge") == 0)
{
- push_state(parser, log_ctx, SUBTRACTIVE_MERGE);
+ push_state(parser, log_ctx, SUBTRACTIVE_MERGE, attrs);
}
else if (strcmp(name.name, "added-path") == 0)
{
const char *copy_path, *copy_rev_str;
- info = push_state(parser, log_ctx, ADDED_PATH);
+ info = push_state(parser, log_ctx, ADDED_PATH, attrs);
info->tmp_path->action = 'A';
copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -266,7 +274,7 @@ start_log(svn_ra_serf__xml_parser_t *par
{
const char *copy_path, *copy_rev_str;
- info = push_state(parser, log_ctx, REPLACED_PATH);
+ info = push_state(parser, log_ctx, REPLACED_PATH, attrs);
info->tmp_path->action = 'R';
copy_path = svn_xml_get_attr_value("copyfrom-path", attrs);
@@ -288,14 +296,14 @@ start_log(svn_ra_serf__xml_parser_t *par
}
else if (strcmp(name.name, "deleted-path") == 0)
{
- info = push_state(parser, log_ctx, DELETED_PATH);
+ info = push_state(parser, log_ctx, DELETED_PATH, attrs);
info->tmp_path->action = 'D';
SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
}
else if (strcmp(name.name, "modified-path") == 0)
{
- info = push_state(parser, log_ctx, MODIFIED_PATH);
+ info = push_state(parser, log_ctx, MODIFIED_PATH, attrs);
info->tmp_path->action = 'M';
SVN_ERR(read_changed_path_attributes(info->tmp_path, attrs));
@@ -305,6 +313,39 @@ start_log(svn_ra_serf__xml_parser_t *par
return SVN_NO_ERROR;
}
+/*
+ * Set *DECODED_CDATA to a copy of current CDATA being tracked in INFO,
+ * decoded as necessary, and allocated from INFO->pool..
+ */
+static svn_error_t *
+maybe_decode_log_cdata(const svn_string_t **decoded_cdata,
+ log_info_t *info)
+{
+ if (info->tmp_encoding)
+ {
+ svn_string_t in;
+ in.data = info->tmp;
+ in.len = info->tmp_len;
+
+ /* Check for a known encoding type. This is easy -- there's
+ only one. */
+ if (strcmp(info->tmp_encoding, "base64") != 0)
+ {
+ return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("Unsupported encoding '%s'"),
+ info->tmp_encoding);
+ }
+
+ *decoded_cdata = svn_base64_decode_string(&in, info->pool);
+ }
+ else
+ {
+ *decoded_cdata = svn_string_ncreate(info->tmp, info->tmp_len,
+ info->pool);
+ }
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
end_log(svn_ra_serf__xml_parser_t *parser,
void *userData,
@@ -361,10 +402,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
{
if (log_ctx->want_author)
{
+ const svn_string_t *decoded_cdata;
+ SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_AUTHOR,
- APR_HASH_KEY_STRING,
- svn_string_ncreate(info->tmp, info->tmp_len,
- info->pool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
info->tmp_len = 0;
svn_ra_serf__xml_pop_state(parser);
@@ -374,10 +415,10 @@ end_log(svn_ra_serf__xml_parser_t *parse
{
if (log_ctx->want_date)
{
+ const svn_string_t *decoded_cdata;
+ SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_DATE,
- APR_HASH_KEY_STRING,
- svn_string_ncreate(info->tmp, info->tmp_len,
- info->pool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
info->tmp_len = 0;
svn_ra_serf__xml_pop_state(parser);
@@ -387,19 +428,20 @@ end_log(svn_ra_serf__xml_parser_t *parse
{
if (log_ctx->want_message)
{
+ const svn_string_t *decoded_cdata;
+ SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
apr_hash_set(info->log_entry->revprops, SVN_PROP_REVISION_LOG,
- APR_HASH_KEY_STRING,
- svn_string_ncreate(info->tmp, info->tmp_len,
- info->pool));
+ APR_HASH_KEY_STRING, decoded_cdata);
}
info->tmp_len = 0;
svn_ra_serf__xml_pop_state(parser);
}
else if (state == REVPROP)
{
+ const svn_string_t *decoded_cdata;
+ SVN_ERR(maybe_decode_log_cdata(&decoded_cdata, info));
apr_hash_set(info->log_entry->revprops, info->revprop_name,
- APR_HASH_KEY_STRING,
- svn_string_ncreate(info->tmp, info->tmp_len, info->pool));
+ APR_HASH_KEY_STRING, decoded_cdata);
info->tmp_len = 0;
svn_ra_serf__xml_pop_state(parser);
}
@@ -562,6 +604,10 @@ create_log_body(serf_bucket_t **body_bkt
}
}
+ svn_ra_serf__add_tag_buckets(buckets,
+ "S:encode-binary-props", NULL,
+ alloc);
+
svn_ra_serf__add_close_tag_buckets(buckets, alloc,
"S:log-report");
Modified: subversion/branches/1.7.x/subversion/mod_dav_svn/reports/log.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/mod_dav_svn/reports/log.c?rev=1230112&r1=1230111&r2=1230112&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/mod_dav_svn/reports/log.c (original)
+++ subversion/branches/1.7.x/subversion/mod_dav_svn/reports/log.c Wed Jan 11
15:57:13 2012
@@ -30,6 +30,7 @@
#include "svn_repos.h"
#include "svn_string.h"
#include "svn_types.h"
+#include "svn_base64.h"
#include "svn_xml.h"
#include "svn_path.h"
#include "svn_dav.h"
@@ -61,6 +62,9 @@ struct log_receiver_baton
/* whether the client requested any custom revprops */
svn_boolean_t requested_custom_revprops;
+
+ /* whether the client can handle encoded binary property values */
+ svn_boolean_t encode_binary_props;
};
@@ -119,35 +123,50 @@ log_receiver(void *baton,
hi = apr_hash_next(hi))
{
char *name;
- svn_string_t *value;
+ void *val;
+ const svn_string_t *value;
+ const char *encoding_str = "";
svn_pool_clear(iterpool);
- apr_hash_this(hi, (void *)&name, NULL, (void *)&value);
+ apr_hash_this(hi, (void *)&name, NULL, &val);
+ value = val;
+
+ /* If the client is okay with us encoding binary (or really,
+ any non-XML-safe) property values, do so as necessary. */
+ if (lrb->encode_binary_props)
+ {
+ if (! svn_xml_is_xml_safe(value->data, value->len))
+ {
+ value = svn_base64_encode_string2(value, TRUE, iterpool);
+ encoding_str = " encoding=\"base64\"";
+ }
+ }
+
if (strcmp(name, SVN_PROP_REVISION_AUTHOR) == 0)
SVN_ERR(dav_svn__brigade_printf
(lrb->bb, lrb->output,
- "<D:creator-displayname>%s</D:creator-displayname>"
- DEBUG_CR,
+ "<D:creator-displayname%s>%s</D:creator-displayname>"
+ DEBUG_CR, encoding_str,
apr_xml_quote_string(iterpool, value->data, 0)));
else if (strcmp(name, SVN_PROP_REVISION_DATE) == 0)
/* ### this should be DAV:creation-date, but we need to format
### that date a bit differently */
SVN_ERR(dav_svn__brigade_printf
(lrb->bb, lrb->output,
- "<S:date>%s</S:date>" DEBUG_CR,
+ "<S:date%s>%s</S:date>" DEBUG_CR, encoding_str,
apr_xml_quote_string(iterpool, value->data, 0)));
else if (strcmp(name, SVN_PROP_REVISION_LOG) == 0)
SVN_ERR(dav_svn__brigade_printf
(lrb->bb, lrb->output,
- "<D:comment>%s</D:comment>" DEBUG_CR,
+ "<D:comment%s>%s</D:comment>" DEBUG_CR, encoding_str,
apr_xml_quote_string(pool,
svn_xml_fuzzy_escape(value->data,
iterpool), 0)));
else
SVN_ERR(dav_svn__brigade_printf
(lrb->bb, lrb->output,
- "<S:revprop name=\"%s\">%s</S:revprop>" DEBUG_CR,
- apr_xml_quote_string(iterpool, name, 0),
+ "<S:revprop name=\"%s\"%s>%s</S:revprop>" DEBUG_CR,
+ apr_xml_quote_string(iterpool, name, 0), encoding_str,
apr_xml_quote_string(iterpool, value->data, 0)));
}
}
@@ -305,6 +324,7 @@ dav_svn__log_report(const dav_resource *
seen_revprop_element = FALSE;
lrb.requested_custom_revprops = FALSE;
+ lrb.encode_binary_props = FALSE;
for (child = doc->root->first_child; child != NULL; child = child->next)
{
/* if this element isn't one of ours, then skip it */
@@ -333,6 +353,8 @@ dav_svn__log_report(const dav_resource *
strict_node_history = TRUE; /* presence indicates positivity */
else if (strcmp(child->name, "include-merged-revisions") == 0)
include_merged_revisions = TRUE; /* presence indicates positivity */
+ else if (strcmp(child->name, "encode-binary-props") == 0)
+ lrb.encode_binary_props = TRUE; /* presence indicates positivity */
else if (strcmp(child->name, "all-revprops") == 0)
{
revprops = NULL; /* presence indicates fetch all revprops */