Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/serf.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/serf.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/serf.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/serf.c 
Fri Jul 26 01:03:26 2013
@@ -137,6 +137,10 @@ load_http_auth_types(apr_pool_t *pool, s
    runtime configuration variable. */
 #define DEFAULT_HTTP_TIMEOUT 600
 
+/* Private symbol for the 1.9-public SVN_CONFIG_OPTION_HTTP_CHUNKED_REQUESTS */
+#define OPTION_HTTP_CHUNKED_REQUESTS "http-chunked-requests"
+
+
 static svn_error_t *
 load_config(svn_ra_serf__session_t *session,
             apr_hash_t *config_hash,
@@ -149,6 +153,7 @@ load_config(svn_ra_serf__session_t *sess
   const char *timeout_str = NULL;
   const char *exceptions;
   apr_port_t proxy_port;
+  svn_tristate_t chunked_requests;
 
   if (config_hash)
     {
@@ -225,6 +230,12 @@ load_config(svn_ra_serf__session_t *sess
                                SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
                                
SVN_CONFIG_DEFAULT_OPTION_HTTP_MAX_CONNECTIONS));
 
+  /* Should we use chunked transfer encoding. */ 
+  SVN_ERR(svn_config_get_tristate(config, &chunked_requests,
+                                  SVN_CONFIG_SECTION_GLOBAL,
+                                  OPTION_HTTP_CHUNKED_REQUESTS,
+                                  "auto", svn_tristate_unknown));
+
   if (config)
     server_group = svn_config_find_group(config,
                                          session->session_url.hostname,
@@ -281,6 +292,12 @@ load_config(svn_ra_serf__session_t *sess
                                    server_group,
                                    SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
                                    session->max_connections));
+
+      /* Should we use chunked transfer encoding. */ 
+      SVN_ERR(svn_config_get_tristate(config, &chunked_requests,
+                                      server_group,
+                                      OPTION_HTTP_CHUNKED_REQUESTS,
+                                      "auto", chunked_requests));
     }
 
   /* Don't allow the http-max-connections value to be larger than our
@@ -355,6 +372,24 @@ load_config(svn_ra_serf__session_t *sess
       session->using_proxy = FALSE;
     }
 
+  /* Setup detect_chunking and using_chunked_requests based on
+   * the chunked_requests tristate */
+  if (chunked_requests == svn_tristate_unknown)
+    {
+      session->detect_chunking = TRUE;
+      session->using_chunked_requests = TRUE;
+    }
+  else if (chunked_requests == svn_tristate_true)
+    {
+      session->detect_chunking = FALSE;
+      session->using_chunked_requests = TRUE;
+    }
+  else /* chunked_requests == svn_tristate_false */
+    {
+      session->detect_chunking = FALSE;
+      session->using_chunked_requests = FALSE;
+    }
+
   /* Setup authentication. */
   SVN_ERR(load_http_auth_types(pool, config, server_group,
                                &session->authn_types));
@@ -442,6 +477,10 @@ svn_ra_serf__open(svn_ra_session_t *sess
      HTTP/1.1 is supported, we can upgrade. */
   serf_sess->http10 = TRUE;
 
+  /* If we switch to HTTP/1.1, then we will use chunked requests. We may 
disable
+     this, if we find an intervening proxy does not support chunked requests.  
*/
+  serf_sess->using_chunked_requests = TRUE;
+
   SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
 
   serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
@@ -486,8 +525,17 @@ svn_ra_serf__open(svn_ra_session_t *sess
   if (err && err->apr_err == APR_EGENERAL)
     err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
                             _("Connection to '%s' failed"), session_URL);
+  SVN_ERR(err);
 
-  return svn_error_trace(err);
+  /* We have set up a useful connection (that doesn't indication a redirect).
+     If we've been told there is possibly a worrisome proxy in our path to the
+     server AND we switched to HTTP/1.1 (chunked requests), then probe for
+     problems in any proxy.  */
+  if ((corrected_url == NULL || *corrected_url == NULL)
+      && serf_sess->detect_chunking && !serf_sess->http10)
+    SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, pool));
+
+  return SVN_NO_ERROR;
 }
 
 /* Implements svn_ra__vtable_t.reparent(). */

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/util.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/util.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/util.c 
Fri Jul 26 01:03:26 2013
@@ -373,10 +373,8 @@ conn_setup(apr_socket_t *sock,
         {
           conn->ssl_context = serf_bucket_ssl_encrypt_context_get(*read_bkt);
 
-#if SERF_VERSION_AT_LEAST(1,0,0)
           serf_ssl_set_hostname(conn->ssl_context,
                                 conn->session->session_url.hostname);
-#endif
 
           serf_ssl_client_cert_provider_set(conn->ssl_context,
                                             svn_ra_serf__handle_client_cert,
@@ -477,7 +475,7 @@ connection_closed(svn_ra_serf__connectio
 {
   if (why)
     {
-      SVN_ERR_MALFUNCTION();
+      return svn_error_wrap_apr(why, NULL);
     }
 
   if (conn->session->using_ssl)
@@ -642,10 +640,10 @@ setup_serf_req(serf_request_t *request,
 {
   serf_bucket_alloc_t *allocator = serf_request_get_alloc(request);
 
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
   svn_spillbuf_t *buf;
+  svn_boolean_t set_CL = session->http10 || !session->using_chunked_requests;
 
-  if (session->http10 && body_bkt != NULL)
+  if (set_CL && body_bkt != NULL)
     {
       /* Ugh. Use HTTP/1.0 to talk to the server because we don't know if
          it speaks HTTP/1.1 (and thus, chunked requests), or because the
@@ -665,7 +663,6 @@ setup_serf_req(serf_request_t *request,
                                                request_pool,
                                                scratch_pool);
     }
-#endif
 
   /* Create a request bucket.  Note that this sucker is kind enough to
      add a "Host" header for us.  */
@@ -674,15 +671,13 @@ setup_serf_req(serf_request_t *request,
 
   /* Set the Content-Length value. This will also trigger an HTTP/1.0
      request (rather than the default chunked request).  */
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
-  if (session->http10)
+  if (set_CL)
     {
       if (body_bkt == NULL)
         serf_bucket_request_set_CL(*req_bkt, 0);
       else
         serf_bucket_request_set_CL(*req_bkt, svn_spillbuf__get_size(buf));
     }
-#endif
 
   *hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
 
@@ -696,10 +691,10 @@ setup_serf_req(serf_request_t *request,
       serf_bucket_headers_setn(*hdrs_bkt, "Content-Type", content_type);
     }
 
-#if SERF_VERSION_AT_LEAST(1, 1, 0)
   if (session->http10)
+    {
       serf_bucket_headers_setn(*hdrs_bkt, "Connection", "keep-alive");
-#endif
+    }
 
   if (accept_encoding)
     {
@@ -2418,8 +2413,10 @@ svn_ra_serf__error_on_status(serf_status
 
       case 411:
         return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
-                                _("DAV request failed: "
-                                  "Content length required"));
+                    _("DAV request failed: 411 Content length required. The "
+                      "server or an intermediate proxy does not accept "
+                      "chunked encoding. Try setting 'http-chunked-requests' "
+                      "to 'auto' or 'no' in your client configuration."));
     }
 
   if (sline.code >= 300)

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/xml.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/xml.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/xml.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_serf/xml.c 
Fri Jul 26 01:03:26 2013
@@ -615,6 +615,14 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
     }
   if (scan->ns == NULL)
     {
+      if (current->state == 0)
+        {
+          return svn_error_createf(
+                        SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+                        _("XML Parsing failed: Unexpected root element '%s'"),
+                        elemname.name);
+        }
+
       xmlctx->waiting = elemname;
       /* ### return?  */
       return SVN_NO_ERROR;

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_svn/client.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_svn/client.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_svn/client.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_ra_svn/client.c 
Fri Jul 26 01:03:26 2013
@@ -1478,16 +1478,19 @@ static svn_error_t *ra_svn_diff(svn_ra_s
 }
 
 
-static svn_error_t *ra_svn_log(svn_ra_session_t *session,
-                               const apr_array_header_t *paths,
-                               svn_revnum_t start, svn_revnum_t end,
-                               int limit,
-                               svn_boolean_t discover_changed_paths,
-                               svn_boolean_t strict_node_history,
-                               svn_boolean_t include_merged_revisions,
-                               const apr_array_header_t *revprops,
-                               svn_log_entry_receiver_t receiver,
-                               void *receiver_baton, apr_pool_t *pool)
+static svn_error_t *
+perform_ra_svn_log(svn_error_t **outer_error,
+                   svn_ra_session_t *session,
+                   const apr_array_header_t *paths,
+                   svn_revnum_t start, svn_revnum_t end,
+                   int limit,
+                   svn_boolean_t discover_changed_paths,
+                   svn_boolean_t strict_node_history,
+                   svn_boolean_t include_merged_revisions,
+                   const apr_array_header_t *revprops,
+                   svn_log_entry_receiver_t receiver,
+                   void *receiver_baton,
+                   apr_pool_t *pool)
 {
   svn_ra_svn__session_baton_t *sess_baton = session->priv;
   svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -1628,8 +1631,10 @@ static svn_error_t *ra_svn_log(svn_ra_se
         cphash = NULL;
 
       nreceived = 0;
-      if (! (limit && (nest_level == 0) && (++nreceived > limit)))
+      if (! (limit && (nest_level == 0) && (++nreceived > limit))
+          && ! *outer_error)
         {
+          svn_error_t *err;
           log_entry = svn_log_entry_create(iterpool);
 
           log_entry->changed_paths = cphash;
@@ -1672,7 +1677,15 @@ static svn_error_t *ra_svn_log(svn_ra_se
                                   SVN_PROP_REVISION_LOG, message);
                 }
             }
-          SVN_ERR(receiver(receiver_baton, log_entry, iterpool));
+          err = receiver(receiver_baton, log_entry, iterpool);
+          if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION)
+            {
+              *outer_error = svn_error_trace(
+                                svn_error_compose_create(*outer_error, err));
+            }
+          else
+            SVN_ERR(err);
+
           if (log_entry->has_children)
             {
               nest_level++;
@@ -1687,9 +1700,40 @@ static svn_error_t *ra_svn_log(svn_ra_se
   svn_pool_destroy(iterpool);
 
   /* Read the response. */
-  return svn_ra_svn__read_cmd_response(conn, pool, "");
+  return svn_error_trace(svn_ra_svn__read_cmd_response(conn, pool, ""));
 }
 
+static svn_error_t *
+ra_svn_log(svn_ra_session_t *session,
+           const apr_array_header_t *paths,
+           svn_revnum_t start, svn_revnum_t end,
+           int limit,
+           svn_boolean_t discover_changed_paths,
+           svn_boolean_t strict_node_history,
+           svn_boolean_t include_merged_revisions,
+           const apr_array_header_t *revprops,
+           svn_log_entry_receiver_t receiver,
+           void *receiver_baton, apr_pool_t *pool)
+{
+  svn_error_t *outer_error = NULL;
+  svn_error_t *err;
+
+  err = svn_error_trace(perform_ra_svn_log(&outer_error,
+                                           session, paths,
+                                           start, end,
+                                           limit,
+                                           discover_changed_paths,
+                                           strict_node_history,
+                                           include_merged_revisions,
+                                           revprops,
+                                           receiver, receiver_baton,
+                                           pool));
+  return svn_error_trace(
+            svn_error_compose_create(outer_error,
+                                     err));
+}
+
+
 
 static svn_error_t *ra_svn_check_path(svn_ra_session_t *session,
                                       const char *path, svn_revnum_t rev,

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/config_file.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/config_file.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/config_file.c 
(original)
+++ 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/config_file.c 
Fri Jul 26 01:03:26 2013
@@ -94,7 +94,7 @@ parser_getc(parse_context_t *ctx, int *c
         }
       else if (ctx->buffer_pos < ctx->buffer_size)
         {
-          *c = ctx->parser_buffer[ctx->buffer_pos];
+          *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos];
           ctx->buffer_pos++;
         }
       else
@@ -107,7 +107,7 @@ parser_getc(parse_context_t *ctx, int *c
 
           if (ctx->buffer_pos < ctx->buffer_size)
             {
-              *c = ctx->parser_buffer[ctx->buffer_pos];
+              *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos];
               ctx->buffer_pos++;
             }
           else
@@ -131,7 +131,7 @@ parser_getc_plain(parse_context_t *ctx, 
 {
   if (ctx->buffer_pos < ctx->buffer_size)
     {
-      *c = ctx->parser_buffer[ctx->buffer_pos];
+      *c = (unsigned char)ctx->parser_buffer[ctx->buffer_pos];
       ctx->buffer_pos++;
 
       return SVN_NO_ERROR;
@@ -189,6 +189,32 @@ skip_to_eoln(parse_context_t *ctx, int *
   return SVN_NO_ERROR;
 }
 
+/* Skip a UTF-8 Byte Order Mark if found. */
+static APR_INLINE svn_error_t *
+skip_bom(parse_context_t *ctx)
+{
+  int ch;
+
+  SVN_ERR(parser_getc(ctx, &ch));
+  if (ch == 0xEF)
+    {
+      const unsigned char *buf = (unsigned char *)ctx->parser_buffer;
+      /* This makes assumptions about the implementation of parser_getc and
+       * the use of skip_bom.  Specifically that parser_getc() will get all
+       * of the BOM characters into the parse_context_t buffer.  This can
+       * safely be assumed as long as we only try to use skip_bom() at the
+       * start of the stream and the buffer is longer than 3 characters. */
+      SVN_ERR_ASSERT(ctx->buffer_size > ctx->buffer_pos + 1);
+      if (buf[ctx->buffer_pos] == 0xBB && buf[ctx->buffer_pos + 1] == 0xBF)
+        ctx->buffer_pos += 2;
+      else
+        SVN_ERR(parser_ungetc(ctx, ch));
+    }
+  else
+    SVN_ERR(parser_ungetc(ctx, ch));
+
+  return SVN_NO_ERROR;
+}
 
 /* Parse a single option value */
 static svn_error_t *
@@ -450,6 +476,8 @@ svn_config__parse_stream(svn_config_t *c
   ctx->buffer_pos = 0;
   ctx->buffer_size = 0;
 
+  SVN_ERR(skip_bom(ctx));
+
   do
     {
       SVN_ERR(skip_whitespace(ctx, &ch, &count));
@@ -806,6 +834,8 @@ svn_config_ensure(const char *config_dir
         "###   http-max-connections       Maximum number of parallel server" NL
         "###                              connections to use for any given"  NL
         "###                              HTTP operation."                   NL
+        "###   http-chunked-requests      Whether to use chunked transfer"   NL
+        "###                              encoding for HTTP requests body."  NL
         "###   neon-debug-mask            Debug mask for Neon HTTP library"  NL
         "###   ssl-authority-files        List of files, each of a trusted CA"
                                                                              NL

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/gpg_agent.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/gpg_agent.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/gpg_agent.c 
(original)
+++ 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/gpg_agent.c 
Fri Jul 26 01:03:26 2013
@@ -156,42 +156,28 @@ send_option(int sd, char *buf, size_t n,
   return (strncmp(buf, "OK", 2) == 0);
 }
 
-/* Implementation of svn_auth__password_get_t that retrieves the password
-   from gpg-agent */
+
+/* Locate a running GPG Agent, and return an open file descriptor
+ * for communication with the agent in *NEW_SD. If no running agent
+ * can be found, set *NEW_SD to -1. */
 static svn_error_t *
-password_get_gpg_agent(svn_boolean_t *done,
-                       const char **password,
-                       apr_hash_t *creds,
-                       const char *realmstring,
-                       const char *username,
-                       apr_hash_t *parameters,
-                       svn_boolean_t non_interactive,
-                       apr_pool_t *pool)
+find_running_gpg_agent(int *new_sd, apr_pool_t *pool)
 {
-  int sd;
+  char *buffer;
   char *gpg_agent_info = NULL;
+  const char *socket_name = NULL;
+  const char *request = NULL;
   const char *p = NULL;
   char *ep = NULL;
-  char *buffer;
-
-  apr_array_header_t *socket_details;
-  const char *request = NULL;
-  const char *cache_id = NULL;
-  struct sockaddr_un addr;
-  const char *tty_name;
-  const char *tty_type;
-  const char *lc_ctype;
-  const char *display;
-  const char *socket_name = NULL;
-  svn_checksum_t *digest = NULL;
-  char *password_prompt;
-  char *realm_prompt;
+  int sd;
 
-  *done = FALSE;
+  *new_sd = -1;
 
   gpg_agent_info = getenv("GPG_AGENT_INFO");
   if (gpg_agent_info != NULL)
     {
+      apr_array_header_t *socket_details;
+
       socket_details = svn_cstring_split(gpg_agent_info, ":", TRUE,
                                          pool);
       socket_name = APR_ARRAY_IDX(socket_details, 0, const char *);
@@ -201,6 +187,8 @@ password_get_gpg_agent(svn_boolean_t *do
 
   if (socket_name != NULL)
     {
+      struct sockaddr_un addr;
+
       addr.sun_family = AF_UNIX;
       strncpy(addr.sun_path, socket_name, sizeof(addr.sun_path) - 1);
       addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
@@ -273,6 +261,44 @@ password_get_gpg_agent(svn_boolean_t *do
       return SVN_NO_ERROR;
     }
 
+  *new_sd = sd;
+  return SVN_NO_ERROR;
+}
+
+/* Implementation of svn_auth__password_get_t that retrieves the password
+   from gpg-agent */
+static svn_error_t *
+password_get_gpg_agent(svn_boolean_t *done,
+                       const char **password,
+                       apr_hash_t *creds,
+                       const char *realmstring,
+                       const char *username,
+                       apr_hash_t *parameters,
+                       svn_boolean_t non_interactive,
+                       apr_pool_t *pool)
+{
+  int sd;
+  const char *p = NULL;
+  char *ep = NULL;
+  char *buffer;
+  const char *request = NULL;
+  const char *cache_id = NULL;
+  const char *tty_name;
+  const char *tty_type;
+  const char *lc_ctype;
+  const char *display;
+  svn_checksum_t *digest = NULL;
+  char *password_prompt;
+  char *realm_prompt;
+
+  *done = FALSE;
+
+  SVN_ERR(find_running_gpg_agent(&sd, pool));
+  if (sd == -1)
+    return SVN_NO_ERROR;
+
+  buffer = apr_palloc(pool, BUFFER_SIZE);
+
   /* Send TTY_NAME to the gpg-agent daemon. */
   tty_name = getenv("GPG_TTY");
   if (tty_name != NULL)
@@ -283,11 +309,6 @@ password_get_gpg_agent(svn_boolean_t *do
           return SVN_NO_ERROR;
         }
     }
-  else
-    {
-      close(sd);
-      return SVN_NO_ERROR;
-    }
 
   /* Send TTY_TYPE to the gpg-agent daemon. */
   tty_type = getenv("TERM");
@@ -299,11 +320,6 @@ password_get_gpg_agent(svn_boolean_t *do
           return SVN_NO_ERROR;
         }
     }
-  else
-    {
-      close(sd);
-      return SVN_NO_ERROR;
-    }
 
   /* Compute LC_CTYPE. */
   lc_ctype = getenv("LC_ALL");
@@ -388,8 +404,8 @@ password_get_gpg_agent(svn_boolean_t *do
    password in GPG Agent if that's how this particular integration
    worked.  But it isn't.  GPG Agent stores the password provided by
    the user via the pinentry program immediately upon its provision
-   (and regardless of its accuracy as passwords go), so there's
-   nothing really to do here.  */
+   (and regardless of its accuracy as passwords go), so we just need
+   to check if a running GPG Agent exists. */
 static svn_error_t *
 password_set_gpg_agent(svn_boolean_t *done,
                        apr_hash_t *creds,
@@ -400,6 +416,15 @@ password_set_gpg_agent(svn_boolean_t *do
                        svn_boolean_t non_interactive,
                        apr_pool_t *pool)
 {
+  int sd;
+
+  *done = FALSE;
+
+  SVN_ERR(find_running_gpg_agent(&sd, pool));
+  if (sd == -1)
+    return SVN_NO_ERROR;
+
+  close(sd);
   *done = TRUE;
 
   return SVN_NO_ERROR;

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/subst.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/subst.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/subst.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/subst.c 
Fri Jul 26 01:03:26 2013
@@ -1944,7 +1944,11 @@ svn_subst_translate_string2(svn_string_t
       return SVN_NO_ERROR;
     }
 
-  if (encoding)
+  if (encoding && !strcmp(encoding, "UTF-8")) 
+    {
+      val_utf8 = value->data;
+    }
+  else if (encoding)
     {
       SVN_ERR(svn_utf_cstring_to_utf8_ex2(&val_utf8, value->data,
                                           encoding, scratch_pool));

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/utf.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/utf.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/utf.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_subr/utf.c Fri 
Jul 26 01:03:26 2013
@@ -233,6 +233,8 @@ xlate_alloc_handle(xlate_handle_node_t *
   else if (apr_err != APR_SUCCESS)
     {
       const char *errstr;
+      char apr_strerr[512];
+
       /* Can't use svn_error_wrap_apr here because it calls functions in
          this file, leading to infinite recursion. */
       if (frompage == SVN_APR_LOCALE_CHARSET)
@@ -248,7 +250,13 @@ xlate_alloc_handle(xlate_handle_node_t *
                               _("Can't create a character converter from "
                                 "'%s' to '%s'"), frompage, topage);
 
-      return svn_error_create(apr_err, NULL, errstr);
+      /* Just put the error on the stack, since svn_error_create duplicates it
+         later.  APR_STRERR will be in the local encoding, not in UTF-8, 
though.
+       */
+      svn_strerror(apr_err, apr_strerr, sizeof(apr_strerr));
+      return svn_error_create(apr_err, 
+                              svn_error_create(apr_err, NULL, apr_strerr),
+                              errstr);
     }
 
   /* Allocate and initialize the node. */

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/adm_ops.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/adm_ops.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/adm_ops.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/adm_ops.c 
Fri Jul 26 01:03:26 2013
@@ -148,6 +148,7 @@ process_committed_leaf(svn_wc__db_t *db,
                                 db, local_abspath,
                                 FALSE /* keep_as_working */,
                                 FALSE /* queue_deletes */,
+                                TRUE  /* remove_locks */,
                                 (! via_recurse)
                                     ? new_revnum : SVN_INVALID_REVNUM,
                                 NULL, NULL,

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/crop.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/crop.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/crop.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/crop.c Fri 
Jul 26 01:03:26 2013
@@ -110,6 +110,7 @@ crop_children(svn_wc__db_t *db,
             SVN_ERR(svn_wc__db_base_remove(db, child_abspath,
                                            FALSE /* keep_as_working */,
                                            FALSE /* queue_deletes */,
+                                           FALSE /* remove_locks */,
                                            SVN_INVALID_REVNUM,
                                            NULL, NULL, iterpool));
 

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/externals.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/externals.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/externals.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/externals.c 
Fri Jul 26 01:03:26 2013
@@ -1413,6 +1413,7 @@ svn_wc__external_remove(svn_wc_context_t
       SVN_ERR(svn_wc__db_base_remove(wc_ctx->db, local_abspath,
                                      FALSE /* keep_as_working */,
                                      TRUE /* queue_deletes */,
+                                     FALSE /* remove_locks */,
                                      SVN_INVALID_REVNUM,
                                      NULL, NULL, scratch_pool));
       SVN_ERR(svn_wc__wq_run(wc_ctx->db, local_abspath,

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/update_editor.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/update_editor.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/update_editor.c 
(original)
+++ 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/update_editor.c 
Fri Jul 26 01:03:26 2013
@@ -924,6 +924,7 @@ mark_directory_edited(struct dir_baton *
       do_notification(db->edit_baton, db->local_abspath, svn_node_dir,
                       svn_wc_notify_tree_conflict, scratch_pool);
       db->already_notified = TRUE;
+
     }
 
   return SVN_NO_ERROR;
@@ -1813,6 +1814,7 @@ delete_entry(const char *path,
       SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
                                      FALSE /* keep_as_working */,
                                      FALSE /* queue_deletes */,
+                                     FALSE /* remove_locks */,
                                      SVN_INVALID_REVNUM /* not_present_rev */,
                                      NULL, NULL,
                                      scratch_pool));
@@ -1911,7 +1913,7 @@ delete_entry(const char *path,
     {
       /* Delete, and do not leave a not-present node.  */
       SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
-                                     keep_as_working, queue_deletes,
+                                     keep_as_working, queue_deletes, FALSE,
                                      SVN_INVALID_REVNUM /* not_present_rev */,
                                      tree_conflict, NULL,
                                      scratch_pool));
@@ -1920,7 +1922,7 @@ delete_entry(const char *path,
     {
       /* Delete, leaving a not-present node.  */
       SVN_ERR(svn_wc__db_base_remove(eb->db, local_abspath,
-                                     keep_as_working, queue_deletes,
+                                     keep_as_working, queue_deletes, FALSE,
                                      *eb->target_revision,
                                      tree_conflict, NULL,
                                      scratch_pool));
@@ -1939,8 +1941,19 @@ delete_entry(const char *path,
 
   /* Notify. */
   if (tree_conflict)
-    do_notification(eb, local_abspath, svn_node_unknown,
-                    svn_wc_notify_tree_conflict, scratch_pool);
+    {
+      if (eb->conflict_func)
+        SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, local_abspath,
+                                                 tree_conflict,
+                                                 NULL /* merge_options */,
+                                                 eb->conflict_func,
+                                                 eb->conflict_baton,
+                                                 eb->cancel_func,
+                                                 eb->cancel_baton,
+                                                 scratch_pool));
+      do_notification(eb, local_abspath, svn_node_unknown,
+                      svn_wc_notify_tree_conflict, scratch_pool);
+    }
   else
     {
       svn_wc_notify_action_t action = svn_wc_notify_update_delete;
@@ -2289,6 +2302,16 @@ add_directory(const char *path,
 
   if (tree_conflict != NULL)
     {
+      if (eb->conflict_func)
+        SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, db->local_abspath,
+                                                 tree_conflict,
+                                                 NULL /* merge_options */,
+                                                 eb->conflict_func,
+                                                 eb->conflict_baton,
+                                                 eb->cancel_func,
+                                                 eb->cancel_baton,
+                                                 pool));
+
       db->already_notified = TRUE;
       do_notification(eb, db->local_abspath, svn_node_dir,
                       svn_wc_notify_tree_conflict, pool);
@@ -3380,6 +3403,16 @@ add_file(const char *path,
                                           tree_conflict, NULL,
                                           scratch_pool));
 
+      if (eb->conflict_func)
+        SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db, fb->local_abspath,
+                                                 tree_conflict,
+                                                 NULL /* merge_options */,
+                                                 eb->conflict_func,
+                                                 eb->conflict_baton,
+                                                 eb->cancel_func,
+                                                 eb->cancel_baton,
+                                                 scratch_pool));
+
       fb->already_notified = TRUE;
       do_notification(eb, fb->local_abspath, svn_node_file,
                       svn_wc_notify_tree_conflict, scratch_pool);
@@ -4703,6 +4736,7 @@ close_edit(void *edit_baton,
               SVN_ERR(svn_wc__db_base_remove(eb->db, eb->target_abspath,
                                              FALSE /* keep_as_working */,
                                              FALSE /* queue_deletes */,
+                                             FALSE /* remove_locks */,
                                              SVN_INVALID_REVNUM,
                                              NULL, NULL, scratch_pool));
             }

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc-queries.sql?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc-queries.sql 
(original)
+++ 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc-queries.sql 
Fri Jul 26 01:03:26 2013
@@ -472,6 +472,10 @@ WHERE wc_id = ?1
 DELETE FROM lock
 WHERE repos_id = ?1 AND repos_relpath = ?2
 
+-- STMT_DELETE_LOCK_RECURSIVELY
+DELETE FROM lock
+WHERE repos_id = ?1 AND (repos_relpath = ?2 OR 
IS_STRICT_DESCENDANT_OF(repos_relpath, ?2))
+
 -- STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE
 UPDATE nodes SET dav_cache = NULL
 WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND op_depth = 0

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.c Fri 
Jul 26 01:03:26 2013
@@ -2086,6 +2086,7 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
                svn_wc__db_t *db, /* For checking conflicts */
                svn_boolean_t keep_as_working,
                svn_boolean_t queue_deletes,
+               svn_boolean_t remove_locks,
                svn_revnum_t not_present_revision,
                svn_skel_t *conflict,
                svn_skel_t *work_items,
@@ -2106,6 +2107,16 @@ db_base_remove(svn_wc__db_wcroot_t *wcro
                                             wcroot, local_relpath,
                                             scratch_pool, scratch_pool));
 
+  if (remove_locks)
+    {
+      svn_sqlite__stmt_t *lock_stmt;
+
+      SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
+                                        STMT_DELETE_LOCK_RECURSIVELY));
+      SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
+      SVN_ERR(svn_sqlite__step_done(lock_stmt));
+    }
+
   if (status == svn_wc__db_status_normal
       && keep_as_working)
     {
@@ -2333,6 +2344,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_boolean_t keep_as_working,
                        svn_boolean_t queue_deletes,
+                       svn_boolean_t remove_locks,
                        svn_revnum_t not_present_revision,
                        svn_skel_t *conflict,
                        svn_skel_t *work_items,
@@ -2349,7 +2361,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
 
   SVN_WC__DB_WITH_TXN(db_base_remove(wcroot, local_relpath,
                                      db, keep_as_working, queue_deletes,
-                                     not_present_revision,
+                                     remove_locks, not_present_revision,
                                      conflict, work_items, scratch_pool),
                       wcroot);
 
@@ -10814,7 +10826,7 @@ commit_node(svn_wc__db_wcroot_t *wcroot,
       svn_sqlite__stmt_t *lock_stmt;
 
       SVN_ERR(svn_sqlite__get_statement(&lock_stmt, wcroot->sdb,
-                                        STMT_DELETE_LOCK));
+                                        STMT_DELETE_LOCK_RECURSIVELY));
       SVN_ERR(svn_sqlite__bindf(lock_stmt, "is", repos_id, repos_relpath));
       SVN_ERR(svn_sqlite__step_done(lock_stmt));
     }
@@ -11058,7 +11070,7 @@ bump_node_revision(svn_wc__db_wcroot_t *
               revision != new_rev)))
     {
       return svn_error_trace(db_base_remove(wcroot, local_relpath,
-                                            db, FALSE, FALSE,
+                                            db, FALSE, FALSE, FALSE,
                                             SVN_INVALID_REVNUM,
                                             NULL, NULL, scratch_pool));
     }

Modified: subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db.h Fri 
Jul 26 01:03:26 2013
@@ -702,6 +702,9 @@ svn_wc__db_base_add_not_present_node(svn
    (With KEEP_AS_WORKING TRUE, this is a no-op, as everything is
     automatically shadowed by the created copy)
 
+   If REMOVE_LOCKS is TRUE, all locks of this node and any subnodes
+   are also removed. This is to be done during commit of deleted nodes.
+
    If NOT_PRESENT_REVISION specifies a valid revision a not-present
    node is installed in BASE node with kind NOT_PRESENT_KIND after
    deleting.
@@ -715,6 +718,7 @@ svn_wc__db_base_remove(svn_wc__db_t *db,
                        const char *local_abspath,
                        svn_boolean_t keep_as_working,
                        svn_boolean_t queue_deletes,
+                       svn_boolean_t remove_locks,
                        svn_revnum_t not_present_revision,
                        svn_skel_t *conflict,
                        svn_skel_t *work_items,

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c 
(original)
+++ 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/wc_db_wcroot.c 
Fri Jul 26 01:03:26 2013
@@ -434,6 +434,8 @@ svn_wc__db_wcroot_parse_local_abspath(sv
   svn_boolean_t always_check = FALSE;
   int wc_format = 0;
   const char *adm_relpath;
+  /* Non-NULL if WCROOT is found through a symlink: */
+  const char *symlink_wcroot_abspath = NULL;
 
   /* ### we need more logic for finding the database (if it is located
      ### outside of the wcroot) and then managing all of that within DB.
@@ -611,6 +613,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
                   if (found_wcroot)
                     break;
 
+                  symlink_wcroot_abspath = local_abspath;
                   SVN_ERR(read_link_target(&local_abspath, local_abspath,
                                            scratch_pool));
 try_symlink_as_dir:
@@ -632,6 +635,7 @@ try_symlink_as_dir:
       local_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
       moved_upwards = TRUE;
+      symlink_wcroot_abspath = NULL;
 
       /* Is the parent directory recorded in our hash?  */
       found_wcroot = svn_hash_gets(db->dir_data, local_abspath);
@@ -669,7 +673,10 @@ try_symlink_as_dir:
          (ie. where we found it).  */
 
       err = svn_wc__db_pdh_create_wcroot(wcroot,
-                            apr_pstrdup(db->state_pool, local_abspath),
+                            apr_pstrdup(db->state_pool,
+                                        symlink_wcroot_abspath
+                                          ? symlink_wcroot_abspath
+                                          : local_abspath),
                             sdb, wc_id, FORMAT_FROM_SDB,
                             db->verify_format, db->enforce_empty_wq,
                             db->state_pool, scratch_pool);
@@ -737,7 +744,10 @@ try_symlink_as_dir:
         }
 
       SVN_ERR(svn_wc__db_pdh_create_wcroot(wcroot,
-                            apr_pstrdup(db->state_pool, local_abspath),
+                            apr_pstrdup(db->state_pool,
+                                        symlink_wcroot_abspath
+                                          ? symlink_wcroot_abspath
+                                          : local_abspath),
                             NULL, UNKNOWN_WC_ID, wc_format,
                             db->verify_format, db->enforce_empty_wq,
                             db->state_pool, scratch_pool));
@@ -747,6 +757,13 @@ try_symlink_as_dir:
     {
       const char *dir_relpath;
 
+      if (symlink_wcroot_abspath)
+        {
+          /* The WCROOT was found through a symlink pointing at the root of
+           * the WC. Cache the WCROOT under the symlink's path. */
+          local_dir_abspath = symlink_wcroot_abspath;
+        }
+
       /* The subdirectory's relpath is easily computed relative to the
          wcroot that we just found.  */
       dir_relpath = compute_relpath(*wcroot, local_dir_abspath, NULL);
@@ -809,6 +826,7 @@ try_symlink_as_dir:
                                              scratch_pool));
           if (resolved_kind == svn_node_dir)
             {
+              symlink_wcroot_abspath = original_abspath;
               SVN_ERR(read_link_target(&local_abspath, original_abspath,
                                        scratch_pool));
               /* This handle was opened in this function but is not going

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/workqueue.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/workqueue.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/workqueue.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/libsvn_wc/workqueue.c 
Fri Jul 26 01:03:26 2013
@@ -143,6 +143,7 @@ run_base_remove(work_item_baton_t *wqb,
   SVN_ERR(svn_wc__db_base_remove(db, local_abspath,
                                  FALSE /* keep_as_working */,
                                  TRUE /* queue_deletes */,
+                                 FALSE /* remove_locks */,
                                  not_present_rev,
                                  NULL, NULL, scratch_pool));
 

Modified: 
subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c?rev=1507168&r1=1507167&r2=1507168&view=diff
==============================================================================
--- subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c 
(original)
+++ subversion/branches/javahl-1.8-extensions/subversion/mod_dav_svn/repos.c 
Fri Jul 26 01:03:26 2013
@@ -2408,21 +2408,12 @@ get_parent_path(const char *path,
                 svn_boolean_t is_urlpath,
                 apr_pool_t *pool)
 {
-  apr_size_t len;
-  char *tmp = apr_pstrdup(pool, path);
-
-  len = strlen(tmp);
-
-  if (len > 0)
+  if (*path != '\0') /* not an empty string */
     {
-      /* Remove any trailing slash; else svn_path_dirname() asserts. */
-      if (tmp[len-1] == '/')
-        tmp[len-1] = '\0';
-
       if (is_urlpath)
-        return svn_urlpath__dirname(tmp, pool);
+        return svn_urlpath__dirname(path, pool);
       else
-        return svn_fspath__dirname(tmp, pool);
+        return svn_fspath__dirname(path, pool);
     }
 
   return path;
@@ -2458,7 +2449,9 @@ get_parent_resource(const dav_resource *
       parent->versioned = 1;
       parent->hooks = resource->hooks;
       parent->pool = resource->pool;
-      parent->uri = get_parent_path(resource->uri, TRUE, resource->pool);
+      parent->uri = get_parent_path(svn_urlpath__canonicalize(resource->uri,
+                                                              resource->pool),
+                                    TRUE, resource->pool);
       parent->info = parentinfo;
 
       parentinfo->uri_path =


Reply via email to