You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by vm...@apache.org on 2012/06/21 07:54:47 UTC

svn commit: r1352418 [4/6] - in /subversion/branches/javahl-ra: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/server-side/ notes/wc-ng/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversio...

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util.c Thu Jun 21 05:54:42 2012
@@ -257,7 +257,7 @@ ssl_server_cert(void *baton, int failure
       int i;
       for (i = 0; i < san->nelts; i++) {
           char *s = APR_ARRAY_IDX(san, i, char*);
-          if (apr_fnmatch(s, conn->hostname,
+          if (apr_fnmatch(s, conn->session->session_url.hostname,
                           APR_FNM_PERIOD) == APR_SUCCESS) {
               found_matching_hostname = 1;
               cert_info.hostname = s;
@@ -269,7 +269,7 @@ ssl_server_cert(void *baton, int failure
   /* Match server certificate CN with the hostname of the server */
   if (!found_matching_hostname && cert_info.hostname)
     {
-      if (apr_fnmatch(cert_info.hostname, conn->hostname,
+      if (apr_fnmatch(cert_info.hostname, conn->session->session_url.hostname,
                       APR_FNM_PERIOD) == APR_FNM_NOMATCH)
         {
           svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
@@ -364,7 +364,7 @@ conn_setup(apr_socket_t *sock,
   *read_bkt = serf_context_bucket_socket_create(conn->session->context,
                                                sock, conn->bkt_alloc);
 
-  if (conn->using_ssl)
+  if (conn->session->using_ssl)
     {
       /* input stream */
       *read_bkt = serf_bucket_ssl_decrypt_create(*read_bkt, conn->ssl_context,
@@ -374,7 +374,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->hostname);
+          serf_ssl_set_hostname(conn->ssl_context,
+                                conn->session->session_url.hostname);
 #endif
 
           serf_ssl_client_cert_provider_set(conn->ssl_context,
@@ -479,7 +480,7 @@ connection_closed(svn_ra_serf__connectio
       SVN_ERR_MALFUNCTION();
     }
 
-  if (conn->using_ssl)
+  if (conn->session->using_ssl)
     conn->ssl_context = NULL;
 
   return SVN_NO_ERROR;
@@ -632,7 +633,7 @@ static svn_error_t *
 setup_serf_req(serf_request_t *request,
                serf_bucket_t **req_bkt,
                serf_bucket_t **hdrs_bkt,
-               svn_ra_serf__connection_t *conn,
+               svn_ra_serf__session_t *session,
                const char *method, const char *url,
                serf_bucket_t *body_bkt, const char *content_type,
                apr_pool_t *request_pool,
@@ -643,7 +644,7 @@ setup_serf_req(serf_request_t *request,
 #if SERF_VERSION_AT_LEAST(1, 1, 0)
   svn_spillbuf_t *buf;
 
-  if (conn->http10 && body_bkt != NULL)
+  if (session->http10 && 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
@@ -669,7 +670,7 @@ 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 (conn->http10)
+  if (session->http10)
     {
       if (body_bkt == NULL)
         serf_bucket_request_set_CL(*req_bkt, 0);
@@ -680,10 +681,10 @@ setup_serf_req(serf_request_t *request,
 
   *hdrs_bkt = serf_bucket_request_get_headers(*req_bkt);
 
-  /* We use serf_bucket_headers_setn() because the string below have a
+  /* We use serf_bucket_headers_setn() because the USERAGENT has a
      lifetime longer than this bucket. Thus, there is no need to copy
      the header values.  */
-  serf_bucket_headers_setn(*hdrs_bkt, "User-Agent", conn->useragent);
+  serf_bucket_headers_setn(*hdrs_bkt, "User-Agent", session->useragent);
 
   if (content_type)
     {
@@ -941,16 +942,29 @@ svn_ra_serf__response_discard_handler(se
   return drain_bucket(response);
 }
 
-const char *
-svn_ra_serf__response_get_location(serf_bucket_t *response,
-                                   apr_pool_t *pool)
+
+/* Return the value of the RESPONSE's Location header if any, or NULL
+   otherwise.  All allocations will be made in POOL.  */
+static const char *
+response_get_location(serf_bucket_t *response,
+                      apr_pool_t *pool)
 {
   serf_bucket_t *headers;
-  const char *val;
+  const char *location;
+  apr_status_t status;
+  apr_uri_t uri;
 
   headers = serf_bucket_response_get_headers(response);
-  val = serf_bucket_headers_get(headers, "Location");
-  return val ? svn_urlpath__canonicalize(val, pool) : NULL;
+  location = serf_bucket_headers_get(headers, "Location");
+  if (location == NULL)
+    return NULL;
+
+  /* Ignore the scheme/host/port. Or just return as-is if we can't parse.  */
+  status = apr_uri_parse(pool, location, &uri);
+  if (!status)
+    location = uri.path;
+
+  return svn_urlpath__canonicalize(location, pool);
 }
 
 
@@ -990,11 +1004,6 @@ svn_ra_serf__expect_empty_body(serf_requ
     }
   else
     {
-      /* ### hmm. this is a bit early. we have not seen EOF. if the
-         ### caller thinks we are "done", then it may never call into
-         ### serf_context_run() again to flush the response.  */
-      handler->done = TRUE;
-
       /* The body was not text/xml, so we don't know what to do with it.
          Toss anything that arrives.  */
       handler->discard_body = TRUE;
@@ -1175,11 +1184,6 @@ svn_ra_serf__handle_multistatus_only(ser
         }
       else
         {
-          /* ### hmm. this is a bit early. we have not seen EOF. if the
-             ### caller thinks we are "done", then it may never call into
-             ### serf_context_run() again to flush the response.  */
-          handler->done = TRUE;
-
           /* The body was not text/xml, so we don't know what to do with it.
              Toss anything that arrives.  */
           handler->discard_body = TRUE;
@@ -1200,6 +1204,7 @@ start_xml(void *userData, const char *ra
   svn_ra_serf__xml_parser_t *parser = userData;
   svn_ra_serf__dav_props_t name;
   apr_pool_t *scratch_pool;
+  svn_error_t *err;
 
   if (parser->error)
     return;
@@ -1214,7 +1219,11 @@ start_xml(void *userData, const char *ra
 
   svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
-  parser->error = parser->start(parser, name, attrs, scratch_pool);
+  err = parser->start(parser, name, attrs, scratch_pool);
+  if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
+    err = svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);
+
+  parser->error = err;
 }
 
 
@@ -1224,6 +1233,7 @@ end_xml(void *userData, const char *raw_
 {
   svn_ra_serf__xml_parser_t *parser = userData;
   svn_ra_serf__dav_props_t name;
+  svn_error_t *err;
   apr_pool_t *scratch_pool;
 
   if (parser->error)
@@ -1234,7 +1244,11 @@ end_xml(void *userData, const char *raw_
 
   svn_ra_serf__expand_ns(&name, parser->state->ns_list, raw_name);
 
-  parser->error = parser->end(parser, name, scratch_pool);
+  err = parser->end(parser, name, scratch_pool);
+  if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
+    err = svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);
+
+  parser->error = err;
 }
 
 
@@ -1243,6 +1257,7 @@ static void
 cdata_xml(void *userData, const char *data, int len)
 {
   svn_ra_serf__xml_parser_t *parser = userData;
+  svn_error_t *err;
   apr_pool_t *scratch_pool;
 
   if (parser->error)
@@ -1254,7 +1269,11 @@ cdata_xml(void *userData, const char *da
   /* ### get a real scratch_pool  */
   scratch_pool = parser->state->pool;
 
-  parser->error = parser->cdata(parser, data, len, scratch_pool);
+  err = parser->cdata(parser, data, len, scratch_pool);
+  if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
+    err = svn_error_create(SVN_ERR_RA_SERF_WRAPPED_ERROR, err, NULL);
+
+  parser->error = err;
 }
 
 /* Flip the requisite bits in CTX to indicate that processing of the
@@ -1404,6 +1423,7 @@ handle_server_error(serf_request_t *requ
   svn_ra_serf__server_error_t server_err = { 0 };
   serf_bucket_t *hdrs;
   const char *val;
+  apr_status_t err;
 
   hdrs = serf_bucket_response_get_headers(response);
   val = serf_bucket_headers_get(hdrs, "Content-Type");
@@ -1443,8 +1463,11 @@ handle_server_error(serf_request_t *requ
     }
 
   /* The only error that we will return is from the XML response body.
-     Otherwise, ignore the entire body and return success.  */
-  (void) drain_bucket(response);
+     Otherwise, ignore the entire body but allow SUCCESS/EOF/EAGAIN to
+     surface. */
+  err = drain_bucket(response);
+  if (err && !SERF_BUCKET_READ_ERROR(err))
+    return svn_error_wrap_apr(err, NULL);
 
   return SVN_NO_ERROR;
 }
@@ -1472,17 +1495,11 @@ svn_ra_serf__handle_xml_parser(serf_requ
   /* Woo-hoo.  Nothing here to see.  */
   if (sl.code == 404 && ctx->ignore_errors == FALSE)
     {
-      add_done_item(ctx);
-
       err = handle_server_error(request, response, pool);
 
-      /* ### the above call should have drained the entire response. this
-         ### call is historical, and probably not required. but during
-         ### the rework of this core handling... let's keep it for now.  */
-      status = drain_bucket(response);
-      if (status)
-        err = svn_error_compose_create(svn_error_wrap_apr(status, NULL),
-                                       err);
+      if (err && APR_STATUS_IS_EOF(err->apr_err))
+        add_done_item(ctx);
+
       return svn_error_trace(err);
     }
 
@@ -1758,6 +1775,10 @@ handle_response(serf_request_t *request,
 
       handler->sline = sl;
       handler->sline.reason = apr_pstrdup(handler->handler_pool, sl.reason);
+
+      /* HTTP/1.1? (or later)  */
+      if (sl.version != SERF_HTTP_10)
+        handler->session->http10 = FALSE;
     }
 
   /* Keep reading from the network until we've read all the headers.  */
@@ -1809,8 +1830,7 @@ handle_response(serf_request_t *request,
     }
 
   /* ... and set up the header fields in HANDLER.  */
-  handler->location = svn_ra_serf__response_get_location(
-                          response, handler->handler_pool);
+  handler->location = response_get_location(response, handler->handler_pool);
 
   /* On the last request, we failed authentication. We succeeded this time,
      so let's save away these credentials.  */
@@ -1830,28 +1850,43 @@ handle_response(serf_request_t *request,
       /* 405 Method Not allowed.
          409 Conflict: can indicate a hook error.
          5xx (Internal) Server error. */
-      /* ### this is completely wrong. it only catches the current network
-         ### packet. we need ongoing parsing. see SERVER_ERROR down below
-         ### in the process_body: area. we'll eventually move to that.  */
-      SVN_ERR(handle_server_error(request, response, scratch_pool));
-
-      if (!handler->session->pending_error)
-        {
-          apr_status_t apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
-
-          /* 405 == Method Not Allowed (Occurs when trying to lock a working
-             copy path which no longer exists at HEAD in the repository. */
-          if (handler->sline.code == 405
-              && strcmp(handler->method, "LOCK") == 0)
-            apr_err = SVN_ERR_FS_OUT_OF_DATE;
+      serf_bucket_t *hdrs;
+      const char *val;
+
+      hdrs = serf_bucket_response_get_headers(response);
+      val = serf_bucket_headers_get(hdrs, "Content-Type");
+      if (val && strncasecmp(val, "text/xml", sizeof("text/xml") - 1) == 0)
+        {
+          svn_ra_serf__server_error_t *server_err;
+
+          server_err = begin_error_parsing(start_error, end_error, cdata_error,
+                                           handler->handler_pool);
+          /* Get the parser to set our DONE flag.  */
+          server_err->parser.done = &handler->done;
+
+          handler->server_error = server_err;
+        }
+      else
+        {
+          handler->discard_body = TRUE;
 
-          return svn_error_createf(apr_err, NULL,
-                                   _("%s request on '%s' failed: %d %s"),
+          if (!handler->session->pending_error)
+            {
+              apr_status_t apr_err = SVN_ERR_RA_DAV_REQUEST_FAILED;
+
+              /* 405 == Method Not Allowed (Occurs when trying to lock a working
+                copy path which no longer exists at HEAD in the repository. */
+              if (handler->sline.code == 405
+                  && strcmp(handler->method, "LOCK") == 0)
+                apr_err = SVN_ERR_FS_OUT_OF_DATE;
+
+              handler->session->pending_error =
+                  svn_error_createf(apr_err, NULL,
+                                    _("%s request on '%s' failed: %d %s"),
                                    handler->method, handler->path,
                                    handler->sline.code, handler->sline.reason);
+            }
         }
-
-      return SVN_NO_ERROR; /* Error is set in caller */
     }
 
   /* Stop processing the above, on every packet arrival.  */
@@ -1863,6 +1898,14 @@ handle_response(serf_request_t *request,
   if (handler->discard_body)
     {
       *serf_status = drain_bucket(response);
+
+      /* If the handler hasn't set done (which it shouldn't have) and
+         we now have the EOF, go ahead and set it so that we can stop
+         our context loops.
+       */
+      if (!handler->done && APR_STATUS_IS_EOF(*serf_status))
+          handler->done = TRUE;
+
       return SVN_NO_ERROR;
     }
 
@@ -1874,17 +1917,25 @@ handle_response(serf_request_t *request,
                                            &handler->server_error->parser,
                                            scratch_pool);
 
-      /* APR_EOF will be returned when parsing is complete.  If we see
-         any other error, return it immediately.
+      /* If we do not receive an error or it is a non-transient error, return
+         immediately.
+
+         APR_EOF will be returned when parsing is complete.
 
-         In practice the only other error we expect to see is APR_EAGAIN,
-         which indicates the network has no more data right now. This
-         svn_error_t will get unwrapped, and that APR_EAGAIN will be
-         returned to serf. We'll get called later, when more network data
-         is available.  */
-      if (!err || !APR_STATUS_IS_EOF(err->apr_err))
+         APR_EAGAIN & WAIT_CONN may be intermittently returned as we proceed through
+         parsing and the network has no more data right now.  If we receive that,
+         clear the error and return - allowing serf to wait for more data.
+         */
+      if (!err || SERF_BUCKET_READ_ERROR(err->apr_err))
         return svn_error_trace(err);
 
+      if (!APR_STATUS_IS_EOF(err->apr_err))
+        {
+          *serf_status = err->apr_err;
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
+        }
+
       /* Clear the EOF. We don't need it.  */
       svn_error_clear(err);
 
@@ -1984,7 +2035,7 @@ setup_request(serf_request_t *request,
     }
 
   SVN_ERR(setup_serf_req(request, req_bkt, &headers_bkt,
-                         handler->conn, handler->method, handler->path,
+                         handler->session, handler->method, handler->path,
                          body_bkt, handler->body_type,
                          request_pool, scratch_pool));
 
@@ -2336,7 +2387,15 @@ expat_response_handler(serf_request_t *r
 {
   struct expat_ctx_t *ectx = baton;
 
-  SVN_ERR_ASSERT(ectx->parser != NULL);
+  if (!ectx->parser)
+    {
+      ectx->parser = XML_ParserCreate(NULL);
+      apr_pool_cleanup_register(ectx->cleanup_pool, &ectx->parser,
+                                xml_parser_cleanup, apr_pool_cleanup_null);
+      XML_SetUserData(ectx->parser, ectx);
+      XML_SetElementHandler(ectx->parser, expat_start, expat_end);
+      XML_SetCharacterDataHandler(ectx->parser, expat_cdata);
+    }
 
   /* ### should we bail on anything < 200 or >= 300 ??
      ### actually: < 200 should really be handled by the core.  */
@@ -2372,6 +2431,20 @@ expat_response_handler(serf_request_t *r
       /* ### should we have an IGNORE_ERRORS flag like the v1 parser?  */
 
       expat_status = XML_Parse(ectx->parser, data, (int)len, 0 /* isFinal */);
+
+      /* We need to check INNER_ERROR first. This is an error from the
+         callbacks that has been "dropped off" for us to retrieve. On
+         current Expat parsers, we stop the parser when an error occurs,
+         so we want to ignore EXPAT_STATUS (which reports the stoppage).
+
+         If an error is not present, THEN we go ahead and look for parsing
+         errors.  */
+      if (ectx->inner_error)
+        {
+          apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
+                               xml_parser_cleanup);
+          return svn_error_trace(ectx->inner_error);
+        }
       if (expat_status == XML_STATUS_ERROR)
         return svn_error_createf(SVN_ERR_XML_MALFORMED,
                                  ectx->inner_error,
@@ -2381,31 +2454,24 @@ expat_response_handler(serf_request_t *r
                                  ectx->handler->sline.code,
                                  ectx->handler->sline.reason);
 
-      /* Was an error dropped off for us?  */
-      if (ectx->inner_error)
-        {
-          apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
-                               xml_parser_cleanup);
-          return svn_error_trace(ectx->inner_error);
-        }
-
       /* The parsing went fine. What has the bucket told us?  */
 
-      if (APR_STATUS_IS_EAGAIN(status))
-        return svn_error_wrap_apr(status, NULL);
-
       if (APR_STATUS_IS_EOF(status))
         {
           /* Tell expat we've reached the end of the content. Ignore the
              return status. We just don't care.  */
           (void) XML_Parse(ectx->parser, NULL, 0, 1 /* isFinal */);
 
+          svn_ra_serf__xml_context_destroy(ectx->xmlctx);
           apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
                                xml_parser_cleanup);
 
           /* ### should check XMLCTX to see if it has returned to the
              ### INITIAL state. we may have ended early...  */
+        }
 
+      if (status && !SERF_BUCKET_READ_ERROR(status))
+        {
           return svn_error_wrap_apr(status, NULL);
         }
     }
@@ -2423,12 +2489,8 @@ svn_ra_serf__create_expat_handler(svn_ra
 
   ectx = apr_pcalloc(result_pool, sizeof(*ectx));
   ectx->xmlctx = xmlctx;
-  ectx->parser = XML_ParserCreate(NULL);
-  apr_pool_cleanup_register(result_pool, &ectx->parser,
-                            xml_parser_cleanup, apr_pool_cleanup_null);
-  XML_SetUserData(ectx->parser, ectx);
-  XML_SetElementHandler(ectx->parser, expat_start, expat_end);
-  XML_SetCharacterDataHandler(ectx->parser, expat_cdata);
+  ectx->parser = NULL;
+  ectx->cleanup_pool = result_pool;
 
 
   handler = apr_pcalloc(result_pool, sizeof(*handler));

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_serf/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_serf/xml.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_serf/xml.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_serf/xml.c Thu Jun 21 05:54:42 2012
@@ -443,6 +443,12 @@ lazy_create_pool(void *baton)
   return xes->state_pool;
 }
 
+void
+svn_ra_serf__xml_context_destroy(
+  svn_ra_serf__xml_context_t *xmlctx)
+{
+  svn_pool_destroy(xmlctx->scratch_pool);
+}
 
 svn_ra_serf__xml_context_t *
 svn_ra_serf__xml_context_create(
@@ -483,12 +489,35 @@ svn_ra_serf__xml_gather_since(svn_ra_ser
                               int stop_state)
 {
   apr_hash_t *data;
+  apr_pool_t *pool;
 
   ensure_pool(xes);
+  pool = xes->state_pool;
+
+  data = apr_hash_make(pool);
+
+  for (; xes != NULL; xes = xes->prev)
+    {
+      if (xes->attrs != NULL)
+        {
+          apr_hash_index_t *hi;
 
-  data = apr_hash_make(xes->state_pool);
+          for (hi = apr_hash_first(pool, xes->attrs); hi;
+               hi = apr_hash_next(hi))
+            {
+              const void *key;
+              apr_ssize_t klen;
+              void *val;
+
+              /* Parent name/value lifetimes are at least as long as POOL.  */
+              apr_hash_this(hi, &key, &klen, &val);
+              apr_hash_set(data, key, klen, val);
+            }
+        }
 
-  /* ### gather data  */
+      if (xes->state == stop_state)
+        break;
+    }
 
   return data;
 }
@@ -560,6 +589,11 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
       if (scan->from_state != current->state)
         continue;
 
+      /* Wildcard tag match.  */
+      if (*scan->name == '*')
+        break;
+
+      /* Found a specific transition.  */
       if (strcmp(elemname.name, scan->name) == 0
           && strcmp(elemname.namespace, scan->ns) == 0)
         break;
@@ -627,7 +661,8 @@ svn_ra_serf__xml_cb_start(svn_ra_serf__x
                 }
 
               if (value)
-                apr_hash_set(new_xes->attrs, name, APR_HASH_KEY_STRING, value);
+                apr_hash_set(new_xes->attrs, name, APR_HASH_KEY_STRING,
+                             apr_pstrdup(new_pool, value));
             }
         }
     }
@@ -746,11 +781,29 @@ svn_ra_serf__xml_cb_cdata(svn_ra_serf__x
                           const char *data,
                           apr_size_t len)
 {
-  /* If we're collecting cdata, but NOT waiting for a closing tag
-     (ie. not within an unknown tag), then copy the cdata.  */
-  if (xmlctx->current->cdata != NULL
-      && xmlctx->waiting.namespace == NULL)
-    svn_stringbuf_appendbytes(xmlctx->current->cdata, data, len);
+  /* If we are waiting for a closing tag, then we are uninterested in
+     the cdata. Just return.  */
+  if (xmlctx->waiting.namespace != NULL)
+    return SVN_NO_ERROR;
+
+  /* If the current state is collecting cdata, then copy the cdata.  */
+  if (xmlctx->current->cdata != NULL)
+    {
+      svn_stringbuf_appendbytes(xmlctx->current->cdata, data, len);
+    }
+  /* ... else if a CDATA_CB has been supplied, then invoke it for
+     all states.  */
+  else if (xmlctx->cdata_cb != NULL)
+    {
+      START_CALLBACK(xmlctx);
+      SVN_ERR(xmlctx->cdata_cb(xmlctx->current,
+                               xmlctx->baton,
+                               xmlctx->current->state,
+                               data, len,
+                               xmlctx->scratch_pool));
+      END_CALLBACK(xmlctx);
+      svn_pool_clear(xmlctx->scratch_pool);
+    }
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_ra_svn/marshal.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_ra_svn/marshal.c Thu Jun 21 05:54:42 2012
@@ -462,7 +462,7 @@ svn_error_t *svn_ra_svn_write_string(svn
 {
   if (str->len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)str->len + '0'));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
@@ -480,7 +480,7 @@ svn_error_t *svn_ra_svn_write_cstring(sv
 
   if (len < 10)
     {
-      SVN_ERR(writebuf_writechar(conn, pool, (char)len + '0'));
+      SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
       SVN_ERR(writebuf_writechar(conn, pool, ':'));
     }
   else
@@ -699,7 +699,7 @@ static svn_error_t *read_string(svn_ra_s
               ? len
               : SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
 
-      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len + 1);
+      svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
       dest = stringbuf->data + stringbuf->len;
     }
 
@@ -1150,7 +1150,7 @@ svn_error_t *svn_ra_svn_write_cmd(svn_ra
   va_start(ap, fmt);
   err = vwrite_tuple(conn, pool, fmt, ap);
   va_end(ap);
-  return err ? err : svn_ra_svn_end_list(conn, pool);
+  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
 }
 
 svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,
@@ -1164,7 +1164,7 @@ svn_error_t *svn_ra_svn_write_cmd_respon
   va_start(ap, fmt);
   err = vwrite_tuple(conn, pool, fmt, ap);
   va_end(ap);
-  return err ? err : svn_ra_svn_end_list(conn, pool);
+  return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
 }
 
 svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/deprecated.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/deprecated.c Thu Jun 21 05:54:42 2012
@@ -775,6 +775,27 @@ fns_from_fns2(const svn_repos_parse_fns2
   return fns;
 }
 
+static svn_repos_parser_fns2_t *
+fns2_from_fns3(const svn_repos_parse_fns3_t *fns3,
+              apr_pool_t *pool)
+{
+  svn_repos_parser_fns2_t *fns2;
+
+  fns2 = apr_palloc(pool, sizeof(*fns2));
+  fns2->new_revision_record = fns3->new_revision_record;
+  fns2->uuid_record = fns3->uuid_record;
+  fns2->new_node_record = fns3->new_node_record;
+  fns2->set_revision_property = fns3->set_revision_property;
+  fns2->set_node_property = fns3->set_node_property;
+  fns2->remove_node_props = fns3->remove_node_props;
+  fns2->set_fulltext = fns3->set_fulltext;
+  fns2->close_node = fns3->close_node;
+  fns2->close_revision = fns3->close_revision;
+  fns2->delete_node_property = fns3->delete_node_property;
+  fns2->apply_textdelta = fns3->apply_textdelta;
+  return fns2;
+}
+
 static svn_repos_parse_fns2_t *
 fns2_from_fns(const svn_repos_parser_fns_t *fns,
               apr_pool_t *pool)
@@ -796,6 +817,42 @@ fns2_from_fns(const svn_repos_parser_fns
   return fns2;
 }
 
+static svn_repos_parse_fns3_t *
+fns3_from_fns2(const svn_repos_parser_fns2_t *fns2,
+               apr_pool_t *pool)
+{
+  svn_repos_parse_fns3_t *fns3;
+
+  fns3 = apr_palloc(pool, sizeof(*fns3));
+  fns3->magic_header_record = NULL;
+  fns3->uuid_record = fns2->uuid_record;
+  fns3->new_revision_record = fns2->new_revision_record;
+  fns3->new_node_record = fns2->new_node_record;
+  fns3->set_revision_property = fns2->set_revision_property;
+  fns3->set_node_property = fns2->set_node_property;
+  fns3->remove_node_props = fns2->remove_node_props;
+  fns3->set_fulltext = fns2->set_fulltext;
+  fns3->close_node = fns2->close_node;
+  fns3->close_revision = fns2->close_revision;
+  fns3->delete_node_property = fns2->delete_node_property;
+  fns3->apply_textdelta = fns2->apply_textdelta;
+  return fns3;
+}
+
+svn_error_t *
+svn_repos_parse_dumpstream2(svn_stream_t *stream,
+                            const svn_repos_parser_fns2_t *parse_fns,
+                            void *parse_baton,
+                            svn_cancel_func_t cancel_func,
+                            void *cancel_baton,
+                            apr_pool_t *pool)
+{
+  svn_repos_parse_fns3_t *fns3 = fns3_from_fns2(parse_fns, pool);
+
+  return svn_repos_parse_dumpstream3(stream, fns3, parse_baton, FALSE,
+                                     cancel_func, cancel_baton, pool);
+}
+
 svn_error_t *
 svn_repos_parse_dumpstream(svn_stream_t *stream,
                            const svn_repos_parser_fns_t *parse_fns,
@@ -837,11 +894,17 @@ svn_repos_get_fs_build_parser3(const svn
                                void *notify_baton,
                                apr_pool_t *pool)
 {
-  return svn_repos_get_fs_build_parser4(callbacks, parse_baton, repos,
-                                        SVN_INVALID_REVNUM, SVN_INVALID_REVNUM,
-                                        use_history, validate_props,
-                                        uuid_action, parent_dir,
-                                        notify_func, notify_baton, pool);
+  const svn_repos_parse_fns3_t *fns3;
+
+  SVN_ERR(svn_repos_get_fs_build_parser4(&fns3, parse_baton, repos,
+                                         SVN_INVALID_REVNUM,
+                                         SVN_INVALID_REVNUM,
+                                         use_history, validate_props,
+                                         uuid_action, parent_dir,
+                                         notify_func, notify_baton, pool));
+
+  *callbacks = fns2_from_fns3(fns3, pool);
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/dump.c Thu Jun 21 05:54:42 2012
@@ -736,7 +736,7 @@ close_directory(void *dir_baton,
   struct dir_baton *db = dir_baton;
   struct edit_baton *eb = db->edit_baton;
   apr_pool_t *subpool = svn_pool_create(pool);
-  unsigned int i;
+  int i;
   apr_array_header_t *sorted_entries;
 
   /* Sort entries lexically instead of as paths. Even though the entries

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/load-fs-vtable.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/load-fs-vtable.c Thu Jun 21 05:54:42 2012
@@ -589,6 +589,13 @@ maybe_add_with_history(struct node_baton
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+magic_header_record(int version,
+                    void *parse_baton,
+                    apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
 
 static svn_error_t *
 uuid_record(const char *uuid,
@@ -1016,7 +1023,7 @@ close_revision(void *baton)
 
 
 svn_error_t *
-svn_repos_get_fs_build_parser4(const svn_repos_parse_fns2_t **callbacks,
+svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks,
                                void **parse_baton,
                                svn_repos_t *repos,
                                svn_revnum_t start_rev,
@@ -1029,7 +1036,7 @@ svn_repos_get_fs_build_parser4(const svn
                                void *notify_baton,
                                apr_pool_t *pool)
 {
-  svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
+  svn_repos_parse_fns3_t *parser = apr_pcalloc(pool, sizeof(*parser));
   struct parse_baton *pb = apr_pcalloc(pool, sizeof(*pb));
 
   if (parent_dir)
@@ -1042,9 +1049,10 @@ svn_repos_get_fs_build_parser4(const svn
   if (SVN_IS_VALID_REVNUM(start_rev))
     SVN_ERR_ASSERT(start_rev <= end_rev);
 
+  parser->magic_header_record = magic_header_record;
+  parser->uuid_record = uuid_record;
   parser->new_revision_record = new_revision_record;
   parser->new_node_record = new_node_record;
-  parser->uuid_record = uuid_record;
   parser->set_revision_property = set_revision_property;
   parser->set_node_property = set_node_property;
   parser->remove_node_props = remove_node_props;
@@ -1093,7 +1101,7 @@ svn_repos_load_fs4(svn_repos_t *repos,
                    void *cancel_baton,
                    apr_pool_t *pool)
 {
-  const svn_repos_parse_fns2_t *parser;
+  const svn_repos_parse_fns3_t *parser;
   void *parse_baton;
   struct parse_baton *pb;
 
@@ -1116,6 +1124,6 @@ svn_repos_load_fs4(svn_repos_t *repos,
   pb->use_pre_commit_hook = use_pre_commit_hook;
   pb->use_post_commit_hook = use_post_commit_hook;
 
-  return svn_repos_parse_dumpstream2(dumpstream, parser, parse_baton,
+  return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE,
                                      cancel_func, cancel_baton, pool);
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/load.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/load.c Thu Jun 21 05:54:42 2012
@@ -181,7 +181,7 @@ read_key_or_val(char **pbuf,
 static svn_error_t *
 parse_property_block(svn_stream_t *stream,
                      svn_filesize_t content_length,
-                     const svn_repos_parse_fns2_t *parse_fns,
+                     const svn_repos_parse_fns3_t *parse_fns,
                      void *record_baton,
                      void *parse_baton,
                      svn_boolean_t is_node,
@@ -299,7 +299,7 @@ static svn_error_t *
 parse_text_block(svn_stream_t *stream,
                  svn_filesize_t content_length,
                  svn_boolean_t is_delta,
-                 const svn_repos_parse_fns2_t *parse_fns,
+                 const svn_repos_parse_fns3_t *parse_fns,
                  void *record_baton,
                  char *buffer,
                  apr_size_t buflen,
@@ -373,7 +373,8 @@ parse_text_block(svn_stream_t *stream,
 /* Parse VERSIONSTRING and verify that we support the dumpfile format
    version number, setting *VERSION appropriately. */
 static svn_error_t *
-parse_format_version(const char *versionstring, int *version)
+parse_format_version(int *version,
+                     const char *versionstring)
 {
   static const int magic_len = sizeof(SVN_REPOS_DUMPFILE_MAGIC_HEADER) - 1;
   const char *p = strchr(versionstring, ':');
@@ -406,9 +407,10 @@ parse_format_version(const char *version
 /** The public routines **/
 
 svn_error_t *
-svn_repos_parse_dumpstream2(svn_stream_t *stream,
-                            const svn_repos_parse_fns2_t *parse_fns,
+svn_repos_parse_dumpstream3(svn_stream_t *stream,
+                            const svn_repos_parse_fns3_t *parse_fns,
                             void *parse_baton,
+                            svn_boolean_t deltas_are_text,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             apr_pool_t *pool)
@@ -428,16 +430,11 @@ svn_repos_parse_dumpstream2(svn_stream_t
     return stream_ran_dry();
 
   /* The first two lines of the stream are the dumpfile-format version
-     number, and a blank line. */
-  SVN_ERR(parse_format_version(linebuf->data, &version));
-
-  /* If we were called from svn_repos_parse_dumpstream(), the
-     callbacks to handle delta contents will be NULL, so we have to
-     reject dumpfiles with the current version. */
-  if (version == SVN_REPOS_DUMPFILE_FORMAT_VERSION
-      && (!parse_fns->delete_node_property || !parse_fns->apply_textdelta))
-    return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
-                             _("Unsupported dumpfile version: %d"), version);
+     number, and a blank line.  To preserve backward compatibility,
+     don't assume the existence of newer parser-vtable functions. */
+  SVN_ERR(parse_format_version(&version, linebuf->data));
+  if (parse_fns->magic_header_record != NULL)
+    SVN_ERR(parse_fns->magic_header_record(version, parse_baton, pool));
 
   /* A dumpfile "record" is defined to be a header-block of
      rfc822-style headers, possibly followed by a content-block.
@@ -528,6 +525,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
           SVN_ERR(parse_fns->uuid_record(value, parse_baton, pool));
         }
       /* Or perhaps a dumpfile format? */
+      /* ### TODO: use parse_format_version */
       else if ((value = apr_hash_get(headers,
                                      SVN_REPOS_DUMPFILE_MAGIC_HEADER,
                                      APR_HASH_KEY_STRING)))
@@ -591,7 +589,9 @@ svn_repos_parse_dumpstream2(svn_stream_t
           const char *delta = apr_hash_get(headers,
                                            SVN_REPOS_DUMPFILE_TEXT_DELTA,
                                            APR_HASH_KEY_STRING);
-          svn_boolean_t is_delta = (delta && strcmp(delta, "true") == 0);
+          svn_boolean_t is_delta = FALSE;
+          if (! deltas_are_text)
+            is_delta = (delta && strcmp(delta, "true") == 0);
 
           SVN_ERR(parse_text_block(stream,
                                    svn__atoui64(text_cl),

Modified: subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c Thu Jun 21 05:54:42 2012
@@ -27,15 +27,18 @@
 
 #include "svn_types.h"
 #include "svn_delta.h"
+#include "svn_hash.h"
 #include "svn_fs.h"
 #include "svn_checksum.h"
 #include "svn_repos.h"
+#include "svn_sorts.h"
 #include "svn_props.h"
 #include "svn_pools.h"
 #include "svn_path.h"
 #include "svn_private_config.h"
 #include "private/svn_fspath.h"
 #include "private/svn_repos_private.h"
+#include "private/svn_delta_private.h"
 
 
 /*** Backstory ***/
@@ -100,6 +103,7 @@
    (though not necessarily in the same order in which they
    occurred). */
 
+/* #define USE_EV2_IMPL */
 
 
 /*** Helper functions. ***/
@@ -137,7 +141,6 @@ struct path_driver_cb_baton
   void *authz_read_baton;
 
   const char *base_path; /* relpath */
-  size_t base_path_len;
 
   svn_revnum_t low_water_mark;
   /* Stack of active copy operations. */
@@ -147,6 +150,7 @@ struct path_driver_cb_baton
   apr_pool_t *pool;
 };
 
+#ifndef USE_EV2_IMPL
 /* Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
    the appropriate editor calls to add it and its children without any
    history.  This is meant to be used when either a subset of the tree
@@ -338,20 +342,7 @@ add_subdir(svn_fs_root_t *source_root,
 
   return SVN_NO_ERROR;
 }
-
-static svn_boolean_t
-is_within_base_path(const char *path, const char *base_path,
-                    apr_ssize_t base_len)
-{
-  if (base_path[0] == '\0')
-    return TRUE;
-
-  if (strncmp(base_path, path, base_len) == 0
-      && (path[base_len] == '/' || path[base_len] == '\0'))
-    return TRUE;
-
-  return FALSE;
-}
+#endif
 
 /* Given PATH deleted under ROOT, return in READABLE whether the path was
    readable prior to the deletion.  Consult COPIES (a stack of 'struct
@@ -468,6 +459,7 @@ fill_copyfrom(svn_fs_root_t **copyfrom_r
   return SVN_NO_ERROR;
 }
 
+#ifndef USE_EV2_IMPL
 static svn_error_t *
 path_driver_cb_func(void **dir_baton,
                     void *parent_baton,
@@ -487,7 +479,6 @@ path_driver_cb_func(void **dir_baton,
   svn_fs_root_t *source_root = cb->compare_root;
   const char *source_fspath = NULL;
   const char *base_path = cb->base_path;
-  size_t base_path_len = cb->base_path_len;
 
   *dir_baton = NULL;
 
@@ -577,8 +568,7 @@ path_driver_cb_func(void **dir_baton,
          all. */
       if (copyfrom_path
           && ((! src_readable)
-              || (! is_within_base_path(copyfrom_path + 1, base_path,
-                                        base_path_len))
+              || (svn_relpath_skip_ancestor(base_path, copyfrom_path + 1) == NULL)
               || (cb->low_water_mark > copyfrom_rev)))
         {
           copyfrom_path = NULL;
@@ -794,6 +784,47 @@ path_driver_cb_func(void **dir_baton,
   return SVN_NO_ERROR;
 }
 
+#else
+
+static svn_error_t *
+fetch_kind_func(svn_kind_t *kind,
+                void *baton,
+                const char *path,
+                svn_revnum_t base_revision,
+                apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *root = baton;
+  svn_node_kind_t node_kind;
+
+  SVN_ERR(svn_fs_check_path(&node_kind, root, path, scratch_pool));
+
+  *kind = svn__kind_from_node_kind(node_kind, FALSE);
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+fetch_props_func(apr_hash_t **props,
+                 void *baton,
+                 const char *path,
+                 svn_revnum_t base_revision,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  svn_fs_root_t *root = baton;
+  svn_fs_root_t *prev_root;
+  svn_fs_t *fs = svn_fs_root_fs(root);
+
+  SVN_ERR(svn_fs_revision_root(&prev_root, fs,
+                               svn_fs_revision_root_revision(root) - 1,
+                               scratch_pool));
+
+  SVN_ERR(svn_fs_node_proplist(props, prev_root, path, result_pool));
+
+  return SVN_NO_ERROR;
+}
+
+#endif
+
 
 
 
@@ -808,12 +839,12 @@ svn_repos_replay2(svn_fs_root_t *root,
                   void *authz_read_baton,
                   apr_pool_t *pool)
 {
+#ifndef USE_EV2_IMPL
   apr_hash_t *fs_changes;
   apr_hash_t *changed_paths;
   apr_hash_index_t *hi;
   apr_array_header_t *paths;
   struct path_driver_cb_baton cb_baton;
-  size_t base_path_len;
 
   /* Special-case r0, which we know is an empty revision; if we don't
      special-case it we might end up trying to compare it to "r-1". */
@@ -831,8 +862,6 @@ svn_repos_replay2(svn_fs_root_t *root,
   else if (base_path[0] == '/')
     ++base_path;
 
-  base_path_len = strlen(base_path);
-
   /* Make an array from the keys of our CHANGED_PATHS hash, and copy
      the values into a new hash whose keys have no leading slashes. */
   paths = apr_array_make(pool, apr_hash_count(fs_changes),
@@ -865,14 +894,14 @@ svn_repos_replay2(svn_fs_root_t *root,
 
           /* If the base_path doesn't match the top directory of this path
              we don't want anything to do with it... */
-          if (is_within_base_path(path, base_path, base_path_len))
+          if (svn_relpath_skip_ancestor(base_path, path) != NULL)
             {
               APR_ARRAY_PUSH(paths, const char *) = path;
               apr_hash_set(changed_paths, path, keylen, change);
             }
           /* ...unless this was a change to one of the parent directories of
              base_path. */
-          else if (is_within_base_path(base_path, path, keylen))
+          else if (svn_relpath_skip_ancestor(path, base_path) != NULL)
             {
               APR_ARRAY_PUSH(paths, const char *) = path;
               apr_hash_set(changed_paths, path, keylen, change);
@@ -893,7 +922,6 @@ svn_repos_replay2(svn_fs_root_t *root,
   cb_baton.authz_read_func = authz_read_func;
   cb_baton.authz_read_baton = authz_read_baton;
   cb_baton.base_path = base_path;
-  cb_baton.base_path_len = base_path_len;
   cb_baton.low_water_mark = low_water_mark;
   cb_baton.compare_root = NULL;
 
@@ -922,17 +950,634 @@ svn_repos_replay2(svn_fs_root_t *root,
   return svn_delta_path_driver(editor, edit_baton,
                                SVN_INVALID_REVNUM, paths,
                                path_driver_cb_func, &cb_baton, pool);
+#else
+  svn_editor_t *editorv2;
+  struct svn_delta__extra_baton *exb;
+  svn_delta__unlock_func_t unlock_func;
+  svn_boolean_t send_abs_paths;
+  const char *repos_root = "";
+  void *unlock_baton;
+
+  /* Special-case r0, which we know is an empty revision; if we don't
+     special-case it we might end up trying to compare it to "r-1". */
+  if (svn_fs_is_revision_root(root)
+        && svn_fs_revision_root_revision(root) == 0)
+    {
+      SVN_ERR(editor->set_target_revision(edit_baton, 0, pool));
+      return SVN_NO_ERROR;
+    }
+
+  /* Determine the revision to use throughout the edit, and call
+     EDITOR's set_target_revision() function.  */
+  if (svn_fs_is_revision_root(root))
+    {
+      svn_revnum_t revision = svn_fs_revision_root_revision(root);
+      SVN_ERR(editor->set_target_revision(edit_baton, revision, pool));
+    }
+
+  if (! base_path)
+    base_path = "";
+  else if (base_path[0] == '/')
+    ++base_path;
+
+  /* Use the shim to convert our editor to an Ev2 editor, and pass it down
+     the stack. */
+  SVN_ERR(svn_delta__editor_from_delta(&editorv2, &exb,
+                                       &unlock_func, &unlock_baton,
+                                       editor, edit_baton,
+                                       &send_abs_paths,
+                                       repos_root, "",
+                                       NULL, NULL,
+                                       fetch_kind_func, root,
+                                       fetch_props_func, root,
+                                       pool, pool));
+
+  /* Tell the shim that we're starting the process. */
+  SVN_ERR(exb->start_edit(exb->baton, svn_fs_revision_root_revision(root)));
+
+  /* ### We're ignoring SEND_DELTAS here. */
+  SVN_ERR(svn_repos__replay_ev2(root, base_path, low_water_mark,
+                                editorv2, authz_read_func, authz_read_baton,
+                                pool));
+
+  return SVN_NO_ERROR;
+#endif
+}
+
+
+/*****************************************************************
+ *                      Ev2 Implementation                       *
+ *****************************************************************/
+
+#ifdef USE_EV2_IMPL
+/* Recursively traverse EDIT_PATH (as it exists under SOURCE_ROOT) emitting
+   the appropriate editor calls to add it and its children without any
+   history.  This is meant to be used when either a subset of the tree
+   has been ignored and we need to copy something from that subset to
+   the part of the tree we do care about, or if a subset of the tree is
+   unavailable because of authz and we need to use it as the source of
+   a copy. */
+static svn_error_t *
+add_subdir(svn_fs_root_t *source_root,
+           svn_fs_root_t *target_root,
+           svn_editor_t *editor,
+           const char *repos_relpath,
+           const char *source_fspath,
+           svn_repos_authz_func_t authz_read_func,
+           void *authz_read_baton,
+           apr_hash_t *changed_paths,
+           apr_pool_t *result_pool,
+           apr_pool_t *scratch_pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_hash_index_t *hi;
+  apr_hash_t *dirents;
+  apr_hash_t *props = NULL;
+  apr_array_header_t *children = NULL;
+
+  SVN_ERR(svn_fs_node_proplist(&props, target_root, repos_relpath,
+                               scratch_pool));
+
+  SVN_ERR(svn_editor_add_directory(editor, repos_relpath, children,
+                                   props, SVN_INVALID_REVNUM));
+
+  /* We have to get the dirents from the source path, not the target,
+     because we want nested copies from *readable* paths to be handled by
+     path_driver_cb_func, not add_subdir (in order to preserve history). */
+  SVN_ERR(svn_fs_dir_entries(&dirents, source_root, source_fspath,
+                             scratch_pool));
+
+  for (hi = apr_hash_first(scratch_pool, dirents); hi; hi = apr_hash_next(hi))
+    {
+      svn_fs_path_change2_t *change;
+      svn_boolean_t readable = TRUE;
+      svn_fs_dirent_t *dent = svn__apr_hash_index_val(hi);
+      const char *copyfrom_path = NULL;
+      svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
+      const char *child_relpath;
+
+      svn_pool_clear(iterpool);
+
+      child_relpath = svn_relpath_join(repos_relpath, dent->name, iterpool);
+
+      /* If a file or subdirectory of the copied directory is listed as a
+         changed path (because it was modified after the copy but before the
+         commit), we remove it from the changed_paths hash so that future
+         calls to path_driver_cb_func will ignore it. */
+      change = apr_hash_get(changed_paths, child_relpath, APR_HASH_KEY_STRING);
+      if (change)
+        {
+          apr_hash_set(changed_paths, child_relpath, APR_HASH_KEY_STRING,
+                       NULL);
+
+          /* If it's a delete, skip this entry. */
+          if (change->change_kind == svn_fs_path_change_delete)
+            continue;
+
+          /* If it's a replacement, check for copyfrom info (if we
+             don't have it already. */
+          if (change->change_kind == svn_fs_path_change_replace)
+            {
+              if (! change->copyfrom_known)
+                {
+                  SVN_ERR(svn_fs_copied_from(&change->copyfrom_rev,
+                                             &change->copyfrom_path,
+                                             target_root, child_relpath,
+                                             result_pool));
+                  change->copyfrom_known = TRUE;
+                }
+              copyfrom_path = change->copyfrom_path;
+              copyfrom_rev = change->copyfrom_rev;
+            }
+        }
+
+      if (authz_read_func)
+        SVN_ERR(authz_read_func(&readable, target_root, child_relpath,
+                                authz_read_baton, iterpool));
+
+      if (! readable)
+        continue;
+
+      if (dent->kind == svn_node_dir)
+        {
+          svn_fs_root_t *new_source_root;
+          const char *new_source_fspath;
+
+          if (copyfrom_path)
+            {
+              svn_fs_t *fs = svn_fs_root_fs(source_root);
+              SVN_ERR(svn_fs_revision_root(&new_source_root, fs,
+                                           copyfrom_rev, result_pool));
+              new_source_fspath = copyfrom_path;
+            }
+          else
+            {
+              new_source_root = source_root;
+              new_source_fspath = svn_fspath__join(source_fspath, dent->name,
+                                                   iterpool);
+            }
+
+          /* ### authz considerations?
+           *
+           * I think not; when path_driver_cb_func() calls add_subdir(), it
+           * passes SOURCE_ROOT and SOURCE_FSPATH that are unreadable.
+           */
+          if (change && change->change_kind == svn_fs_path_change_replace
+              && copyfrom_path == NULL)
+            {
+              SVN_ERR(svn_editor_add_directory(editor, child_relpath,
+                                               children, props,
+                                               SVN_INVALID_REVNUM));
+            }
+          else
+            {
+              SVN_ERR(add_subdir(new_source_root, target_root,
+                                 editor, child_relpath,
+                                 new_source_fspath,
+                                 authz_read_func, authz_read_baton,
+                                 changed_paths, result_pool, iterpool));
+            }
+        }
+      else if (dent->kind == svn_node_file)
+        {
+          svn_checksum_t *checksum;
+          svn_stream_t *contents;
+
+          SVN_ERR(svn_fs_node_proplist(&props, target_root,
+                                       child_relpath, iterpool));
+
+          SVN_ERR(svn_fs_file_contents(&contents, target_root,
+                                       child_relpath, iterpool));
+
+          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
+                                       target_root,
+                                       child_relpath, TRUE, iterpool));
+
+          SVN_ERR(svn_editor_add_file(editor, child_relpath, checksum,
+                                      contents, props, SVN_INVALID_REVNUM));
+        }
+      else
+        SVN_ERR_MALFUNCTION();
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+#endif
+
+static svn_error_t *
+replay_node(svn_fs_root_t *root,
+            const char *repos_relpath,
+            svn_editor_t *editor,
+            svn_revnum_t low_water_mark,
+            const char *base_repos_relpath,
+            apr_array_header_t *copies,
+            apr_hash_t *changed_paths,
+            svn_repos_authz_func_t authz_read_func,
+            void *authz_read_baton,
+            apr_pool_t *result_pool,
+            apr_pool_t *scratch_pool)
+#ifndef USE_EV2_IMPL
+{
+  SVN__NOT_IMPLEMENTED();
+}
+#else
+{
+  svn_fs_path_change2_t *change;
+  svn_boolean_t do_add = FALSE;
+  svn_boolean_t do_delete = FALSE;
+  svn_revnum_t copyfrom_rev;
+  const char *copyfrom_path;
+  svn_revnum_t replaces_rev;
+
+  /* First, flush the copies stack so it only contains ancestors of path. */
+  while (copies->nelts > 0
+         && (svn_relpath_skip_ancestor(APR_ARRAY_IDX(copies,
+                                                    copies->nelts - 1,
+                                                     struct copy_info *)->path,
+                                       repos_relpath) == NULL) )
+    apr_array_pop(copies);
+
+  change = apr_hash_get(changed_paths, repos_relpath, APR_HASH_KEY_STRING);
+  if (! change)
+    {
+      /* This can only happen if the path was removed from changed_paths
+         by an earlier call to add_subdir, which means the path was already
+         handled and we should simply ignore it. */
+      return SVN_NO_ERROR;
+    }
+  switch (change->change_kind)
+    {
+    case svn_fs_path_change_add:
+      do_add = TRUE;
+      break;
+
+    case svn_fs_path_change_delete:
+      do_delete = TRUE;
+      break;
+
+    case svn_fs_path_change_replace:
+      do_add = TRUE;
+      do_delete = TRUE;
+      break;
+
+    case svn_fs_path_change_modify:
+    default:
+      /* do nothing */
+      break;
+    }
+
+  /* Handle any deletions. */
+  if (do_delete && ! do_add)
+    {
+      svn_boolean_t readable;
+
+      /* Issue #4121: delete under under a copy, of a path that was unreadable
+         at its pre-copy location. */
+      SVN_ERR(was_readable(&readable, root, repos_relpath, copies,
+                            authz_read_func, authz_read_baton,
+                            scratch_pool, scratch_pool));
+      if (readable)
+        SVN_ERR(svn_editor_delete(editor, repos_relpath, SVN_INVALID_REVNUM));
+
+      return SVN_NO_ERROR;
+    }
+
+  /* Handle replacements. */
+  if (do_delete && do_add)
+    replaces_rev = svn_fs_revision_root_revision(root);
+  else
+    replaces_rev = SVN_INVALID_REVNUM;
+
+  /* Fetch the node kind if it makes sense to do so. */
+  if (! do_delete || do_add)
+    {
+      if (change->node_kind == svn_node_unknown)
+        SVN_ERR(svn_fs_check_path(&(change->node_kind), root, repos_relpath,
+                                  scratch_pool));
+      if ((change->node_kind != svn_node_dir) &&
+          (change->node_kind != svn_node_file))
+        return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
+                                 _("Filesystem path '%s' is neither a file "
+                                   "nor a directory"), repos_relpath);
+    }
+
+  /* Handle any adds/opens. */
+  if (do_add)
+    {
+      svn_boolean_t src_readable;
+      svn_fs_root_t *copyfrom_root;
+
+      /* Was this node copied? */
+      SVN_ERR(fill_copyfrom(&copyfrom_root, &copyfrom_path, &copyfrom_rev,
+                            &src_readable, root, change,
+                            authz_read_func, authz_read_baton,
+                            repos_relpath, scratch_pool, scratch_pool));
+
+      /* If we have a copyfrom path, and we can't read it or we're just
+         ignoring it, or the copyfrom rev is prior to the low water mark
+         then we just null them out and do a raw add with no history at
+         all. */
+      if (copyfrom_path
+          && ((! src_readable)
+              || (svn_relpath_skip_ancestor(base_repos_relpath,
+                                            copyfrom_path + 1) == NULL)
+              || (low_water_mark > copyfrom_rev)))
+        {
+          copyfrom_path = NULL;
+          copyfrom_rev = SVN_INVALID_REVNUM;
+        }
+
+      /* Do the right thing based on the path KIND. */
+      if (change->node_kind == svn_node_dir)
+        {
+          /* If this is a copy, but we can't represent it as such,
+             then we just do a recursive add of the source path
+             contents. */
+          if (change->copyfrom_path && ! copyfrom_path)
+            {
+              SVN_ERR(add_subdir(copyfrom_root, root, editor,
+                                 repos_relpath, change->copyfrom_path,
+                                 authz_read_func, authz_read_baton,
+                                 changed_paths, result_pool, scratch_pool));
+            }
+          else
+            {
+              if (copyfrom_path)
+                {
+                  if (copyfrom_path[0] == '/')
+                    ++copyfrom_path;
+                  SVN_ERR(svn_editor_copy(editor, copyfrom_path, copyfrom_rev,
+                                          repos_relpath, replaces_rev));
+                }
+              else
+                {
+                  apr_array_header_t *children;
+                  apr_hash_t *props;
+                  apr_hash_t *dirents;
+
+                  SVN_ERR(svn_fs_dir_entries(&dirents, root, repos_relpath,
+                                             scratch_pool));
+                  SVN_ERR(svn_hash_keys(&children, dirents, scratch_pool));
+
+                  SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                               scratch_pool));
+
+                  SVN_ERR(svn_editor_add_directory(editor, repos_relpath,
+                                                   children, props,
+                                                   replaces_rev));
+                }
+            }
+        }
+      else
+        {
+          if (copyfrom_path)
+            {
+              if (copyfrom_path[0] == '/')
+                ++copyfrom_path;
+              SVN_ERR(svn_editor_copy(editor, copyfrom_path, copyfrom_rev,
+                                      repos_relpath, replaces_rev));
+            }
+          else
+            {
+              apr_hash_t *props;
+              svn_checksum_t *checksum;
+              svn_stream_t *contents;
+
+              SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                           scratch_pool));
+
+              SVN_ERR(svn_fs_file_contents(&contents, root, repos_relpath,
+                                           scratch_pool));
+
+              SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1, root,
+                                           repos_relpath, TRUE, scratch_pool));
+
+              SVN_ERR(svn_editor_add_file(editor, repos_relpath, checksum,
+                                          contents, props, replaces_rev));
+            }
+        }
+
+      /* If we represent this as a copy... */
+      if (copyfrom_path)
+        {
+          /* If it is a directory, make sure descendants get the correct
+             delta source by remembering that we are operating inside a
+             (possibly nested) copy operation. */
+          if (change->node_kind == svn_node_dir)
+            {
+              struct copy_info *info = apr_pcalloc(result_pool, sizeof(*info));
+
+              info->path = apr_pstrdup(result_pool, repos_relpath);
+              info->copyfrom_path = apr_pstrdup(result_pool, copyfrom_path);
+              info->copyfrom_rev = copyfrom_rev;
+
+              APR_ARRAY_PUSH(copies, struct copy_info *) = info;
+            }
+        }
+      else
+        /* Else, we are an add without history... */
+        {
+          /* If an ancestor is added with history, we need to forget about
+             that here, go on with life and repeat all the mistakes of our
+             past... */
+          if (change->node_kind == svn_node_dir && copies->nelts > 0)
+            {
+              struct copy_info *info = apr_pcalloc(result_pool, sizeof(*info));
+
+              info->path = apr_pstrdup(result_pool, repos_relpath);
+              info->copyfrom_path = NULL;
+              info->copyfrom_rev = SVN_INVALID_REVNUM;
+
+              APR_ARRAY_PUSH(copies, struct copy_info *) = info;
+            }
+        }
+    }
+  else if (! do_delete)
+    {
+      /* If we are inside an add with history, we need to adjust the
+         delta source. */
+      if (copies->nelts > 0)
+        {
+          struct copy_info *info = APR_ARRAY_IDX(copies,
+                                                 copies->nelts - 1,
+                                                 struct copy_info *);
+          if (info->copyfrom_path)
+            {
+              const char *relpath = svn_relpath_skip_ancestor(info->path,
+                                                              repos_relpath);
+              SVN_ERR_ASSERT(relpath && *relpath);
+              repos_relpath = svn_relpath_join(info->copyfrom_path,
+                                               relpath, scratch_pool);
+            }
+        }
+    }
+
+  if (! do_delete && !do_add)
+    {
+      apr_hash_t *props = NULL;
+
+      /* Is this a copy that was downgraded to a raw add?  (If so,
+         we'll need to transmit properties and file contents and such
+         for it regardless of what the CHANGE structure's text_mod
+         and prop_mod flags say.)  */
+      svn_boolean_t downgraded_copy = (change->copyfrom_known
+                                       && change->copyfrom_path
+                                       && (! copyfrom_path));
+
+      /* Handle property modifications. */
+      if (change->prop_mod || downgraded_copy)
+        {
+          SVN_ERR(svn_fs_node_proplist(&props, root, repos_relpath,
+                                       scratch_pool));
+        }
+
+      /* Handle textual modifications. */
+      if (change->node_kind == svn_node_file
+          && (change->text_mod || change->prop_mod || downgraded_copy))
+        {
+          svn_checksum_t *checksum;
+          svn_stream_t *contents;
+
+          SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
+                                       root, repos_relpath, TRUE,
+                                       scratch_pool));
+
+          SVN_ERR(svn_fs_file_contents(&contents, root, repos_relpath,
+                                       scratch_pool));
+
+          SVN_ERR(svn_editor_alter_file(editor, repos_relpath,
+                                        SVN_INVALID_REVNUM, props, checksum,
+                                        contents));
+        }
+
+      if (change->node_kind == svn_node_dir
+          && (change->prop_mod || downgraded_copy))
+        {
+          apr_array_header_t *children = NULL;
+
+          SVN_ERR(svn_editor_alter_directory(editor, repos_relpath,
+                                             SVN_INVALID_REVNUM, children,
+                                             props));
+        }
+    }
+
+  return SVN_NO_ERROR;
 }
+#endif
 
 svn_error_t *
 svn_repos__replay_ev2(svn_fs_root_t *root,
-                      const char *base_dir,
+                      const char *base_repos_relpath,
                       svn_revnum_t low_water_mark,
-                      svn_boolean_t send_deltas,
                       svn_editor_t *editor,
                       svn_repos_authz_func_t authz_read_func,
                       void *authz_read_baton,
                       apr_pool_t *scratch_pool)
 {
-  SVN__NOT_IMPLEMENTED();
+  apr_hash_t *fs_changes;
+  apr_hash_t *changed_paths;
+  apr_hash_index_t *hi;
+  apr_array_header_t *paths;
+  apr_array_header_t *copies;
+  apr_pool_t *iterpool;
+  svn_error_t *err = SVN_NO_ERROR;
+  int i;
+
+  SVN_ERR_ASSERT(!svn_dirent_is_absolute(base_repos_relpath));
+
+  /* Special-case r0, which we know is an empty revision; if we don't
+     special-case it we might end up trying to compare it to "r-1". */
+  if (svn_fs_is_revision_root(root)
+        && svn_fs_revision_root_revision(root) == 0)
+    {
+      return SVN_NO_ERROR;
+    }
+
+  /* Fetch the paths changed under ROOT. */
+  SVN_ERR(svn_fs_paths_changed2(&fs_changes, root, scratch_pool));
+
+  /* Make an array from the keys of our CHANGED_PATHS hash, and copy
+     the values into a new hash whose keys have no leading slashes. */
+  paths = apr_array_make(scratch_pool, apr_hash_count(fs_changes),
+                         sizeof(const char *));
+  changed_paths = apr_hash_make(scratch_pool);
+  for (hi = apr_hash_first(scratch_pool, fs_changes); hi;
+        hi = apr_hash_next(hi))
+    {
+      const void *key;
+      void *val;
+      apr_ssize_t keylen;
+      const char *path;
+      svn_fs_path_change2_t *change;
+      svn_boolean_t allowed = TRUE;
+
+      apr_hash_this(hi, &key, &keylen, &val);
+      path = key;
+      change = val;
+
+      if (authz_read_func)
+        SVN_ERR(authz_read_func(&allowed, root, path, authz_read_baton,
+                                scratch_pool));
+
+      if (allowed)
+        {
+          if (path[0] == '/')
+            {
+              path++;
+              keylen--;
+            }
+
+          /* If the base_path doesn't match the top directory of this path
+             we don't want anything to do with it... */
+          if (svn_relpath_skip_ancestor(base_repos_relpath, path) != NULL)
+            {
+              APR_ARRAY_PUSH(paths, const char *) = path;
+              apr_hash_set(changed_paths, path, keylen, change);
+            }
+          /* ...unless this was a change to one of the parent directories of
+             base_path. */
+          else if (svn_relpath_skip_ancestor(path, base_repos_relpath) != NULL)
+            {
+              APR_ARRAY_PUSH(paths, const char *) = path;
+              apr_hash_set(changed_paths, path, keylen, change);
+            }
+        }
+    }
+
+  /* If we were not given a low water mark, assume that everything is there,
+     all the way back to revision 0. */
+  if (! SVN_IS_VALID_REVNUM(low_water_mark))
+    low_water_mark = 0;
+
+  copies = apr_array_make(scratch_pool, 4, sizeof(struct copy_info *));
+
+  /* Sort the paths.  Although not strictly required by the API, this has
+     the pleasant side effect of maintaining a consistent ordering of
+     dumpfile contents. */
+  qsort(paths->elts, paths->nelts, paths->elt_size, svn_sort_compare_paths);
+
+  /* Now actually handle the various paths. */
+  iterpool = svn_pool_create(scratch_pool);
+  for (i = 0; i < paths->nelts; i++)
+    {
+      const char *repos_relpath = APR_ARRAY_IDX(paths, i, const char *);
+
+      svn_pool_clear(iterpool);
+      err = replay_node(root, repos_relpath, editor, low_water_mark,
+                        base_repos_relpath, copies, changed_paths,
+                        authz_read_func, authz_read_baton,
+                        scratch_pool, iterpool);
+      if (err)
+        break;
+    }
+
+  if (err)
+    return svn_error_compose_create(err, svn_editor_abort(editor));
+  else
+    SVN_ERR(svn_editor_complete(editor));
+
+  svn_pool_destroy(iterpool);
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/adler32.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/adler32.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/adler32.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/adler32.c Thu Jun 21 05:54:42 2012
@@ -61,7 +61,9 @@ svn__adler32(apr_uint32_t checksum, cons
        * optimized code. Also, new zlib versions will come with
        * SIMD code for x86 and x64.
        */
-      return adler32(checksum, (const Bytef *)data, len);
+      return (apr_uint32_t)adler32(checksum,
+                                   (const Bytef *)data,
+                                   (uInt)len);
     }
   else
     {

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/auth.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/auth.c Thu Jun 21 05:54:42 2012
@@ -441,11 +441,12 @@ svn_auth_get_platform_specific_provider(
             {
               svn_version_func_t version_function
                 = version_function_symbol;
-              const svn_version_checklist_t check_list[] =
-                {
-                  { library_label, version_function },
-                  { NULL, NULL }
-                };
+              svn_version_checklist_t check_list[2];
+
+              check_list[0].label = library_label;
+              check_list[0].version_query = version_function;
+              check_list[1].label = NULL;
+              check_list[1].version_query = NULL;
               SVN_ERR(svn_ver_check_list(svn_subr_version(), check_list));
             }
           if (apr_dso_sym(&provider_function_symbol,

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/base64.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/base64.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/base64.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/base64.c Thu Jun 21 05:54:42 2012
@@ -306,9 +306,9 @@ struct decode_baton {
 static APR_INLINE void
 decode_group(const unsigned char *in, char *out)
 {
-  out[0] = (in[0] << 2) | (in[1] >> 4);
-  out[1] = ((in[1] & 0xf) << 4) | (in[2] >> 2);
-  out[2] = ((in[2] & 0x3) << 6) | in[3];
+  out[0] = (char)((in[0] << 2) | (in[1] >> 4));
+  out[1] = (char)(((in[1] & 0xf) << 4) | (in[2] >> 2));
+  out[2] = (char)(((in[2] & 0x3) << 6) | in[3]);
 }
 
 /* Lookup table for base64 characters; reverse_base64[ch] gives a
@@ -415,9 +415,9 @@ decode_bytes(svn_stringbuf_t *str, const
      (*inbuflen+len) is encoded data length
      (*inbuflen+len)/4 is the number of complete 4-bytes sets
      (*inbuflen+len)/4*3 is the number of decoded bytes
-     (*inbuflen+len)/4*3+1 is the number of decoded bytes plus a null
+     svn_stringbuf_ensure will add an additional byte for the terminating 0.
   */
-  svn_stringbuf_ensure(str, str->len + ((*inbuflen + len) / 4) * 3 + 1);
+  svn_stringbuf_ensure(str, str->len + ((*inbuflen + len) / 4) * 3);
 
   while ( !*done && p < end )
     {

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/cache-membuffer.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/cache-membuffer.c Thu Jun 21 05:54:42 2012
@@ -700,9 +700,11 @@ let_entry_age(svn_membuffer_t *cache, en
 static APR_INLINE unsigned char
 is_group_initialized(svn_membuffer_t *cache, apr_uint32_t group_index)
 {
-  unsigned char flags = cache->group_initialized
-                          [group_index / (8 * GROUP_INIT_GRANULARITY)];
-  unsigned char bit_mask = 1 << ((group_index / GROUP_INIT_GRANULARITY) % 8);
+  unsigned char flags
+    = cache->group_initialized[group_index / (8 * GROUP_INIT_GRANULARITY)];
+  unsigned char bit_mask
+    = (unsigned char)(1 << ((group_index / GROUP_INIT_GRANULARITY) % 8));
+
   return flags & bit_mask;
 }
 
@@ -726,7 +728,8 @@ initialize_group(svn_membuffer_t *cache,
         cache->directory[i][j].offset = NO_OFFSET;
 
   /* set the "initialized" bit for these groups */
-  bit_mask = 1 << ((group_index / GROUP_INIT_GRANULARITY) % 8);
+  bit_mask
+    = (unsigned char)(1 << ((group_index / GROUP_INIT_GRANULARITY) % 8));
   cache->group_initialized[group_index / (8 * GROUP_INIT_GRANULARITY)]
     |= bit_mask;
 }
@@ -1075,11 +1078,10 @@ svn_cache__membuffer_cache_create(svn_me
    * Note, that this limit could only be exceeded in a very
    * theoretical setup with about 1EB of cache.
    */
-  group_count = directory_size / sizeof(entry_group_t);
-  if (group_count >= (APR_UINT32_MAX / GROUP_SIZE))
-    {
-      group_count = (APR_UINT32_MAX / GROUP_SIZE) - 1;
-    }
+  group_count = directory_size / sizeof(entry_group_t)
+                    >= (APR_UINT32_MAX / GROUP_SIZE)
+              ? (APR_UINT32_MAX / GROUP_SIZE) - 1
+              : (apr_uint32_t)(directory_size / sizeof(entry_group_t));
 
   group_init_size = 1 + group_count / (8 * GROUP_INIT_GRANULARITY);
   for (seg = 0; seg < segment_count; ++seg)

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/cache-memcache.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/cache-memcache.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/cache-memcache.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/cache-memcache.c Thu Jun 21 05:54:42 2012
@@ -29,6 +29,7 @@
 
 #include "svn_private_config.h"
 #include "private/svn_cache.h"
+#include "private/svn_dep_compat.h"
 
 #include "cache.h"
 
@@ -527,7 +528,7 @@ svn_cache__make_memcache_from_config(svn
                                     svn_config_t *config,
                                     apr_pool_t *pool)
 {
-  apr_uint16_t server_count;
+  int server_count;
   apr_pool_t *subpool = svn_pool_create(pool);
 
   server_count =
@@ -542,12 +543,15 @@ svn_cache__make_memcache_from_config(svn
       return SVN_NO_ERROR;
     }
 
+  if (server_count > APR_INT16_MAX)
+    return svn_error_create(SVN_ERR_TOO_MANY_MEMCACHED_SERVERS, NULL, NULL);
+
 #ifdef SVN_HAVE_MEMCACHE
   {
     struct ams_baton b;
     svn_memcache_t *memcache = apr_pcalloc(pool, sizeof(*memcache));
     apr_status_t apr_err = apr_memcache_create(pool,
-                                               server_count,
+                                               (apr_uint16_t)server_count,
                                                0, /* flags */
                                                &(memcache->c));
     if (apr_err != APR_SUCCESS)

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/cache.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/cache.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/cache.c Thu Jun 21 05:54:42 2012
@@ -212,14 +212,14 @@ svn_cache__format_info(const svn_cache__
   enum { _1MB = 1024 * 1024 };
 
   apr_uint64_t misses = info->gets - info->hits;
-  double hit_rate = (100.0 * info->hits)
-                  / (info->gets ? info->gets : 1);
-  double write_rate = (100.0 * info->sets)
-                    / (misses ? misses : 1);
-  double data_usage_rate = (100.0 * info->used_size)
-                         / (info->data_size ? info->data_size : 1);
-  double data_entry_rate = (100.0 * info->used_entries)
-                         / (info->total_entries ? info->total_entries : 1);
+  double hit_rate = (100.0 * (double)info->hits)
+                  / (double)(info->gets ? info->gets : 1);
+  double write_rate = (100.0 * (double)info->sets)
+                    / (double)(misses ? misses : 1);
+  double data_usage_rate = (100.0 * (double)info->used_size)
+                         / (double)(info->data_size ? info->data_size : 1);
+  double data_entry_rate = (100.0 * (double)info->used_entries)
+                 / (double)(info->total_entries ? info->total_entries : 1);
 
   return svn_string_createf(result_pool,
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/checksum.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/checksum.c Thu Jun 21 05:54:42 2012
@@ -276,8 +276,8 @@ svn_checksum_parse_hex(svn_checksum_t **
       if (x1 == (char)-1 || x2 == (char)-1)
         return svn_error_create(SVN_ERR_BAD_CHECKSUM_PARSE, NULL, NULL);
 
-      digest[i] = (x1 << 4) | x2;
-      is_nonzero |= (x1 << 4) | x2;
+      digest[i] = (char)((x1 << 4) | x2);
+      is_nonzero |= (char)((x1 << 4) | x2);
     }
 
   if (!is_nonzero)

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/config_file.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/config_file.c Thu Jun 21 05:54:42 2012
@@ -797,9 +797,6 @@ svn_config_ensure(const char *config_dir
                                                                              NL
         "###   http-compression           Whether to compress HTTP requests" NL
         "###   neon-debug-mask            Debug mask for Neon HTTP library"  NL
-#ifdef SVN_NEON_0_26
-        "###   http-auth-types            Auth types to use for HTTP library"NL
-#endif
         "###   ssl-authority-files        List of files, each of a trusted CA"
                                                                              NL
         "###   ssl-trust-default-ca       Trust the system 'default' CAs"    NL
@@ -809,7 +806,7 @@ svn_config_ensure(const char *config_dir
         "###   ssl-pkcs11-provider        Name of PKCS#11 provider to use."  NL
         "###   http-library               Which library to use for http/https"
                                                                              NL
-        "###                              connections (neon or serf)"        NL
+        "###                              connections."                      NL
         "###   store-passwords            Specifies whether passwords used"  NL
         "###                              to authenticate against a"         NL
         "###                              Subversion server may be cached"   NL
@@ -887,6 +884,13 @@ svn_config_ensure(const char *config_dir
         "### HTTP timeouts, if given, are specified in seconds.  A timeout"  NL
         "### of 0, i.e. zero, causes a builtin default to be used."          NL
         "###"                                                                NL
+        "### Most users will not need to explicitly set the http-library"    NL
+        "### option, but valid values for the option include:"               NL
+        "###    'serf': Serf-based module (Subversion 1.5 - present)"        NL
+        "###    'neon': Neon-based module (Subversion 1.0 - 1.7)"            NL
+        "### Availability of these modules may depend on your specific"      NL
+        "### Subversion distribution."                                       NL
+        "###"                                                                NL
         "### The commented-out examples below are intended only to"          NL
         "### demonstrate how to use this file; any resemblance to actual"    NL
         "### servers, living or dead, is entirely coincidental."             NL
@@ -908,9 +912,6 @@ svn_config_ensure(const char *config_dir
         "# http-proxy-username = blah"                                       NL
         "# http-proxy-password = doubleblah"                                 NL
         "# http-timeout = 60"                                                NL
-#ifdef SVN_NEON_0_26
-        "# http-auth-types = basic;digest;negotiate"                         NL
-#endif
         "# neon-debug-mask = 130"                                            NL
 #ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE
         "# store-plaintext-passwords = no"                                   NL
@@ -951,9 +952,6 @@ svn_config_ensure(const char *config_dir
         "# http-proxy-username = defaultusername"                            NL
         "# http-proxy-password = defaultpassword"                            NL
         "# http-compression = no"                                            NL
-#ifdef SVN_NEON_0_26
-        "# http-auth-types = basic;digest;negotiate"                         NL
-#endif
         "# No http-timeout, so just use the builtin default."                NL
         "# No neon-debug-mask, so neon debugging is disabled."               NL
         "# ssl-authority-files = /path/to/CAcert.pem;/path/to/CAcert2.pem"   NL

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/dirent_uri.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/dirent_uri.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/dirent_uri.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/dirent_uri.c Thu Jun 21 05:54:42 2012
@@ -104,7 +104,7 @@ canonicalize_to_lower(char c)
   if (c < 'A' || c > 'Z')
     return c;
   else
-    return c - 'A' + 'a';
+    return (char)(c - 'A' + 'a');
 }
 
 /* Locale insensitive toupper() for converting parts of dirents and urls
@@ -115,7 +115,7 @@ canonicalize_to_upper(char c)
   if (c < 'a' || c > 'z')
     return c;
   else
-    return c - 'a' + 'A';
+    return (char)(c - 'a' + 'A');
 }
 
 /* Calculates the length of the dirent absolute or non absolute root in

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/io.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/io.c Thu Jun 21 05:54:42 2012
@@ -1391,28 +1391,32 @@ get_default_file_perms(apr_fileperms_t *
     {
       apr_finfo_t finfo;
       apr_file_t *fd;
+      const char *fname_base, *fname;
+      apr_uint32_t randomish;
+      svn_error_t *err;
 
       /* Get the perms for a newly created file to find out what bits
         should be set.
 
-        Normally del_on_close can be problematic because APR might
-        delete the file if we spawned any child processes. In this
-        case, the lifetime of this file handle is about 3 lines of
-        code, so we can safely use del_on_close here.
-
-        Not so fast! If some other thread forks off a child, then the
-        APR cleanups run, and the file will disappear. So use
-        del_on_pool_cleanup instead.
+        Explictly delete the file because we want this file to be as
+        short-lived as possible since its presence means other
+        processes may have to try multiple names.
 
         Using svn_io_open_uniquely_named() here because other tempfile
         creation functions tweak the permission bits of files they create.
       */
-      SVN_ERR(svn_io_open_uniquely_named(&fd, NULL, NULL, "default-perms", NULL,
-                                         svn_io_file_del_on_pool_cleanup,
-                                         scratch_pool, scratch_pool));
-      SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool));
-      SVN_ERR(svn_io_file_close(fd, scratch_pool));
+      randomish = ((apr_uint32_t)(apr_uintptr_t)scratch_pool
+                   + (apr_uint32_t)apr_time_now());
+      fname_base = apr_psprintf(scratch_pool, "svn-%08x", randomish);
 
+      SVN_ERR(svn_io_open_uniquely_named(&fd, &fname, NULL, fname_base,
+                                         NULL, svn_io_file_del_none,
+                                         scratch_pool, scratch_pool));
+      err = svn_io_file_info_get(&finfo, APR_FINFO_PROT, fd, scratch_pool);
+      err = svn_error_compose_create(err, svn_io_file_close(fd, scratch_pool));
+      err = svn_error_compose_create(err, svn_io_remove_file2(fname, TRUE,
+                                                              scratch_pool));
+      SVN_ERR(err);
       *perms = finfo.protection;
       default_perms = finfo.protection;
     }
@@ -2126,7 +2130,7 @@ stringbuf_from_aprfile(svn_stringbuf_t *
         {
           apr_finfo_t finfo;
           if (! (status = apr_stat(&finfo, filename, APR_FINFO_MIN, pool)))
-            res_initial_len = finfo.size;
+            res_initial_len = (apr_size_t)finfo.size;
         }
     }
 
@@ -4020,8 +4024,8 @@ contents_identical_p(svn_boolean_t *iden
   apr_size_t bytes_read1, bytes_read2;
   char *buf1 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
   char *buf2 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);
-  apr_file_t *file1_h = NULL;
-  apr_file_t *file2_h = NULL;
+  apr_file_t *file1_h;
+  apr_file_t *file2_h;
   svn_boolean_t eof1 = FALSE;
   svn_boolean_t eof2 = FALSE;
 
@@ -4084,16 +4088,16 @@ svn_io_files_contents_same_p(svn_boolean
 
   if (q)
     {
-      *same = 0;
+      *same = FALSE;
       return SVN_NO_ERROR;
     }
 
   SVN_ERR(contents_identical_p(&q, file1, file2, pool));
 
   if (q)
-    *same = 1;
+    *same = TRUE;
   else
-    *same = 0;
+    *same = FALSE;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/path.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/path.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/path.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/path.c Thu Jun 21 05:54:42 2012
@@ -1168,8 +1168,8 @@ illegal_path_escape(const char *path, ap
         svn_stringbuf_appendbytes(retstr, path + copied,
                                   i - copied);
 
-      /* Make sure buffer is big enough for '\' 'N' 'N' 'N' null */
-      svn_stringbuf_ensure(retstr, retstr->len + 5);
+      /* Make sure buffer is big enough for '\' 'N' 'N' 'N' (and NUL) */
+      svn_stringbuf_ensure(retstr, retstr->len + 4);
       /*### The backslash separator doesn't work too great with Windows,
          but it's what we'll use for consistency with invalid utf8
          formatting (until someone has a better idea) */

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/pool.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/pool.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/pool.c Thu Jun 21 05:54:42 2012
@@ -53,6 +53,7 @@ abort_on_pool_failure(int retcode)
      And we don't have any of it... */
   printf("Out of memory - terminating application.\n");
   abort();
+  return 0; /* not reached */
 }
 
 

Modified: subversion/branches/javahl-ra/subversion/libsvn_subr/quoprint.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_subr/quoprint.c?rev=1352418&r1=1352417&r2=1352418&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_subr/quoprint.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_subr/quoprint.c Thu Jun 21 05:54:42 2012
@@ -233,7 +233,7 @@ decode_bytes(svn_stringbuf_t *str, const
           find2 = strchr(hextab, inbuf[2]);
           if (find1 != NULL && find2 != NULL)
             {
-              c = ((find1 - hextab) << 4) | (find2 - hextab);
+              c = (char)(((find1 - hextab) << 4) | (find2 - hextab));
               svn_stringbuf_appendbyte(str, c);
             }
           *inbuflen = 0;