subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cmpil...@apache.org
Subject svn commit: r1215375 - /subversion/trunk/subversion/libsvn_ra_serf/log.c
Date Sat, 17 Dec 2011 00:59:51 GMT
Author: cmpilato
Date: Sat Dec 17 00:59:51 2011
New Revision: 1215375

URL: http://svn.apache.org/viewvc?rev=1215375&view=rev
Log:
Finish the libsvn_ra_serf client-side bit of issue #4082.  This should
complete the issue.

Pass along in the XML REPORT request for log revisions a flag which
means "encode any binary property values before trying to send them
across the wire".  Check the server's response for instances of said
encoding occuring, and adjust the parsing of the response accordingly.

* subversion/libsvn_ra_serf/log.c
  (log_info_t): Add 'tmp_encoding' member.
  (start_log): Check for and squirrel away any "encoding" attribute
    value on property-related tags.
  (maybe_decode_log_cdata): New helper.
  (end_log): Use maybe_decode_log_cdata() to get the CDATA associated
    with property-related tags into a digestable form.
  (create_log_body): Add "encode-binary-props" self-closing XML tag to
    the REPORT body.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/log.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/log.c?rev=1215375&r1=1215374&r2=1215375&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/log.c Sat Dec 17 00:59:51 2011
@@ -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;
@@ -209,26 +213,41 @@ start_log(svn_ra_serf__xml_parser_t *par
         }
       else if (strcmp(name.name, "creator-displayname") == 0)
         {
-          push_state(parser, log_ctx, CREATOR);
+          const char *tmp_encoding =
+            svn_xml_get_attr_value("encoding", attrs);
+          info = push_state(parser, log_ctx, CREATOR);
+          if (tmp_encoding)
+            info->tmp_encoding = apr_pstrdup(info->pool, tmp_encoding);
         }
       else if (strcmp(name.name, "date") == 0)
         {
-          push_state(parser, log_ctx, DATE);
+          const char *tmp_encoding =
+            svn_xml_get_attr_value("encoding", attrs);
+          info = push_state(parser, log_ctx, DATE);
+          if (tmp_encoding)
+            info->tmp_encoding = apr_pstrdup(info->pool, tmp_encoding);
         }
       else if (strcmp(name.name, "comment") == 0)
         {
-          push_state(parser, log_ctx, COMMENT);
+          const char *tmp_encoding =
+            svn_xml_get_attr_value("encoding", attrs);
+          info = push_state(parser, log_ctx, COMMENT);
+          if (tmp_encoding)
+            info->tmp_encoding = apr_pstrdup(info->pool, tmp_encoding);
         }
       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);
+          const char *tmp_encoding =
+            svn_xml_get_attr_value("encoding", 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);
           info->revprop_name = apr_pstrdup(info->pool, revprop_name);
+          if (tmp_encoding)
+            info->tmp_encoding = apr_pstrdup(info->pool, tmp_encoding);
         }
       else if (strcmp(name.name, "has-children") == 0)
         {
@@ -305,6 +324,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 +413,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 +426,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 +439,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 +615,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");
 



Mime
View raw message