subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From i...@apache.org
Subject svn commit: r1658954 [2/22] - in /subversion/branches/reuse-ra-session: ./ build/generator/ build/generator/templates/ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwrapper/ subversion/bindings/swig/ subversion/include/ subver...
Date Wed, 11 Feb 2015 13:29:28 GMT
Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra/ra_loader.c Wed Feb 11 13:29:26 2015
@@ -52,6 +52,7 @@
 #include "ra_loader.h"
 #include "deprecated.h"
 
+#include "private/svn_auth_private.h"
 #include "private/svn_ra_private.h"
 #include "svn_private_config.h"
 
@@ -273,22 +274,12 @@ svn_error_t *svn_ra_open4(svn_ra_session
   svn_ra_session_t *session;
   const struct ra_lib_defn *defn;
   const svn_ra__vtable_t *vtable = NULL;
-  svn_config_t *servers = NULL;
-  const char *server_group = NULL;
   apr_uri_t repos_URI;
   apr_status_t apr_err;
   svn_error_t *err;
 #ifdef CHOOSABLE_DAV_MODULE
   const char *http_library = DEFAULT_HTTP_LIBRARY;
 #endif
-  /* Auth caching parameters. */
-  svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
-  svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
-  const char *store_plaintext_passwords
-    = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS;
-  svn_boolean_t store_pp = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP;
-  const char *store_pp_plaintext
-    = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT;
 
   /* Initialize the return variable. */
   *session_p = NULL;
@@ -304,100 +295,27 @@ svn_error_t *svn_ra_open4(svn_ra_session
                              repos_URL);
 
   if (callbacks->auth_baton)
-    {
-      /* The 'store-passwords' and 'store-auth-creds' parameters used to
-       * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
-       * if values for these parameters have already been set by our
-       * callers, we use those values as defaults.
-       *
-       * Note that we can only catch the case where users explicitly set
-       * "store-passwords = no" or 'store-auth-creds = no".
-       *
-       * However, since the default value for both these options is
-       * currently (and has always been) "yes", users won't know
-       * the difference if they set "store-passwords = yes" or
-       * "store-auth-creds = yes" -- they'll get the expected behaviour.
-       */
-
-      if (svn_auth_get_parameter(callbacks->auth_baton,
-                                 SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
-        store_passwords = FALSE;
-
-      if (svn_auth_get_parameter(callbacks->auth_baton,
-                                 SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
-        store_auth_creds = FALSE;
-    }
+    SVN_ERR(svn_auth__apply_config_for_server(callbacks->auth_baton, config,
+                                              repos_URI.hostname, sesspool));
 
+#ifdef CHOOSABLE_DAV_MODULE
   if (config)
     {
+      svn_config_t *servers = NULL;
+      const char *server_group = NULL;
+
       /* Grab the 'servers' config. */
       servers = svn_hash_gets(config, SVN_CONFIG_CATEGORY_SERVERS);
       if (servers)
         {
           /* First, look in the global section. */
 
-          SVN_ERR(svn_config_get_bool
-            (servers, &store_passwords, SVN_CONFIG_SECTION_GLOBAL,
-             SVN_CONFIG_OPTION_STORE_PASSWORDS,
-             store_passwords));
-
-          SVN_ERR(svn_config_get_yes_no_ask
-            (servers, &store_plaintext_passwords, SVN_CONFIG_SECTION_GLOBAL,
-             SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
-             SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
-
-          SVN_ERR(svn_config_get_bool
-            (servers, &store_pp, SVN_CONFIG_SECTION_GLOBAL,
-             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
-             store_pp));
-
-          SVN_ERR(svn_config_get_yes_no_ask
-            (servers, &store_pp_plaintext,
-             SVN_CONFIG_SECTION_GLOBAL,
-             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
-             SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT));
-
-          SVN_ERR(svn_config_get_bool
-            (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
-              SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
-              store_auth_creds));
-
           /* Find out where we're about to connect to, and
            * try to pick a server group based on the destination. */
           server_group = svn_config_find_group(servers, repos_URI.hostname,
                                                SVN_CONFIG_SECTION_GROUPS,
                                                sesspool);
 
-          if (server_group)
-            {
-              /* Override global auth caching parameters with the ones
-               * for the server group, if any. */
-              SVN_ERR(svn_config_get_bool(servers, &store_auth_creds,
-                                          server_group,
-                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
-                                          store_auth_creds));
-
-              SVN_ERR(svn_config_get_bool(servers, &store_passwords,
-                                          server_group,
-                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
-                                          store_passwords));
-
-              SVN_ERR(svn_config_get_yes_no_ask
-                (servers, &store_plaintext_passwords, server_group,
-                 SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
-                 store_plaintext_passwords));
-
-              SVN_ERR(svn_config_get_bool
-                (servers, &store_pp,
-                 server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
-                 store_pp));
-
-              SVN_ERR(svn_config_get_yes_no_ask
-                (servers, &store_pp_plaintext, server_group,
-                 SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
-                 store_pp_plaintext));
-            }
-#ifdef CHOOSABLE_DAV_MODULE
           /* Now, which DAV-based RA method do we want to use today? */
           http_library
             = svn_config_get_server_setting(servers,
@@ -410,38 +328,9 @@ svn_error_t *svn_ra_open4(svn_ra_session
                                      _("Invalid config: unknown HTTP library "
                                        "'%s'"),
                                      http_library);
-#endif
         }
     }
-
-  if (callbacks->auth_baton)
-    {
-      /* Save auth caching parameters in the auth parameter hash. */
-      if (! store_passwords)
-        svn_auth_set_parameter(callbacks->auth_baton,
-                               SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
-
-      svn_auth_set_parameter(callbacks->auth_baton,
-                             SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
-                             store_plaintext_passwords);
-
-      if (! store_pp)
-        svn_auth_set_parameter(callbacks->auth_baton,
-                               SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
-                               "");
-
-      svn_auth_set_parameter(callbacks->auth_baton,
-                             SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
-                             store_pp_plaintext);
-
-      if (! store_auth_creds)
-        svn_auth_set_parameter(callbacks->auth_baton,
-                               SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
-
-      if (server_group)
-        svn_auth_set_parameter(callbacks->auth_baton,
-                               SVN_AUTH_PARAM_SERVER_GROUP, server_group);
-    }
+#endif
 
   /* Find the library. */
   for (defn = ra_libraries; defn->ra_name != NULL; ++defn)

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/editorp.c Wed Feb 11 13:29:26 2015
@@ -91,7 +91,7 @@ typedef struct ra_svn_driver_state_t {
    different purpose instead: at apply-textdelta time, we set it to a
    subpool of the file pool, which is destroyed in textdelta-end. */
 typedef struct ra_svn_token_entry_t {
-  const char *token;
+  svn_string_t *token;
   void *baton;
   svn_boolean_t is_file;
   svn_stream_t *dstream;  /* svndiff stream for apply_textdelta */
@@ -465,27 +465,31 @@ void svn_ra_svn_get_editor(const svn_del
 
 /* Store a token entry.  The token string will be copied into pool. */
 static ra_svn_token_entry_t *store_token(ra_svn_driver_state_t *ds,
-                                         void *baton, const char *token,
+                                         void *baton,
+                                         svn_string_t *token,
                                          svn_boolean_t is_file,
                                          apr_pool_t *pool)
 {
   ra_svn_token_entry_t *entry;
 
   entry = apr_palloc(pool, sizeof(*entry));
-  entry->token = apr_pstrdup(pool, token);
+  entry->token = svn_string_dup(token, pool);
   entry->baton = baton;
   entry->is_file = is_file;
   entry->dstream = NULL;
   entry->pool = pool;
-  svn_hash_sets(ds->tokens, entry->token, entry);
+
+  apr_hash_set(ds->tokens, entry->token->data, entry->token->len, entry);
+
   return entry;
 }
 
-static svn_error_t *lookup_token(ra_svn_driver_state_t *ds, const char *token,
+static svn_error_t *lookup_token(ra_svn_driver_state_t *ds,
+                                 svn_string_t *token,
                                  svn_boolean_t is_file,
                                  ra_svn_token_entry_t **entry)
 {
-  *entry = svn_hash_gets(ds->tokens, token);
+  *entry = apr_hash_get(ds->tokens, token->data, token->len);
   if (!*entry || (*entry)->is_file != is_file)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("Invalid file or dir token during edit"));
@@ -511,10 +515,10 @@ static svn_error_t *ra_svn_handle_open_r
 {
   svn_revnum_t rev;
   apr_pool_t *subpool;
-  const char *token;
+  svn_string_t *token;
   void *root_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)c", &rev, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)s", &rev, &token));
   subpool = svn_pool_create(ds->pool);
   SVN_CMD_ERR(ds->editor->open_root(ds->edit_baton, rev, subpool,
                                     &root_baton));
@@ -527,11 +531,12 @@ static svn_error_t *ra_svn_handle_delete
                                                const apr_array_header_t *params,
                                                ra_svn_driver_state_t *ds)
 {
-  const char *path, *token;
+  const char *path;
+  svn_string_t *token;
   svn_revnum_t rev;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)c",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)s",
                                   &path, &rev, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   path = svn_relpath_canonicalize(path, pool);
@@ -544,13 +549,14 @@ static svn_error_t *ra_svn_handle_add_di
                                           const apr_array_header_t *params,
                                           ra_svn_driver_state_t *ds)
 {
-  const char *path, *token, *child_token, *copy_path;
+  const char *path, *copy_path;
+  svn_string_t *token, *child_token;
   svn_revnum_t copy_rev;
   ra_svn_token_entry_t *entry;
   apr_pool_t *subpool;
   void *child_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?cr)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
                                   &child_token, &copy_path, &copy_rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   subpool = svn_pool_create(entry->pool);
@@ -577,13 +583,14 @@ static svn_error_t *ra_svn_handle_open_d
                                            const apr_array_header_t *params,
                                            ra_svn_driver_state_t *ds)
 {
-  const char *path, *token, *child_token;
+  const char *path;
+  svn_string_t *token, *child_token;
   svn_revnum_t rev;
   ra_svn_token_entry_t *entry;
   apr_pool_t *subpool;
   void *child_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?r)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
                                   &child_token, &rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   subpool = svn_pool_create(entry->pool);
@@ -599,11 +606,12 @@ static svn_error_t *ra_svn_handle_change
                                                   const apr_array_header_t *params,
                                                   ra_svn_driver_state_t *ds)
 {
-  const char *token, *name;
+  svn_string_t *token;
+  const char *name;
   svn_string_t *value;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc(?s)", &token, &name,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
                                   &value));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   SVN_CMD_ERR(ds->editor->change_dir_prop(entry->baton, name, value,
@@ -616,11 +624,11 @@ static svn_error_t *ra_svn_handle_close_
                                             const apr_array_header_t *params,
                                             ra_svn_driver_state_t *ds)
 {
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
 
   /* Parse and look up the directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Close the directory and destroy the baton. */
@@ -636,11 +644,11 @@ static svn_error_t *ra_svn_handle_absent
                                              ra_svn_driver_state_t *ds)
 {
   const char *path;
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
 
   /* Parse parameters and look up the directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc", &path, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Call the editor. */
@@ -653,15 +661,19 @@ static svn_error_t *ra_svn_handle_add_fi
                                            const apr_array_header_t *params,
                                            ra_svn_driver_state_t *ds)
 {
-  const char *path, *token, *file_token, *copy_path;
+  const char *path, *copy_path;
+  svn_string_t *token, *file_token;
   svn_revnum_t copy_rev;
   ra_svn_token_entry_t *entry, *file_entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?cr)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
                                   &file_token, &copy_path, &copy_rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   ds->file_refs++;
-  path = svn_relpath_canonicalize(path, pool);
+
+  /* The PATH should be canonical .. but never trust incoming data. */
+  if (!svn_relpath_is_canonical(path))
+    path = svn_relpath_canonicalize(path, pool);
 
   /* Some operations pass COPY_PATH as a full URL (commits, etc.).
      Others (replay, e.g.) deliver an fspath.  That's ... annoying. */
@@ -684,15 +696,20 @@ static svn_error_t *ra_svn_handle_open_f
                                             const apr_array_header_t *params,
                                             ra_svn_driver_state_t *ds)
 {
-  const char *path, *token, *file_token;
+  const char *path;
+  svn_string_t *token, *file_token;
   svn_revnum_t rev;
   ra_svn_token_entry_t *entry, *file_entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ccc(?r)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
                                   &file_token, &rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   ds->file_refs++;
-  path = svn_relpath_canonicalize(path, pool);
+
+  /* The PATH should be canonical .. but never trust incoming data. */
+  if (!svn_relpath_is_canonical(path))
+    path = svn_relpath_canonicalize(path, pool);
+
   file_entry = store_token(ds, NULL, file_token, TRUE, ds->file_pool);
   SVN_CMD_ERR(ds->editor->open_file(path, entry->baton, rev, ds->file_pool,
                                     &file_entry->baton));
@@ -704,14 +721,14 @@ static svn_error_t *ra_svn_handle_apply_
                                                   const apr_array_header_t *params,
                                                   ra_svn_driver_state_t *ds)
 {
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
   svn_txdelta_window_handler_t wh;
   void *wh_baton;
   char *base_checksum;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
                                   &token, &base_checksum));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (entry->dstream)
@@ -729,12 +746,12 @@ static svn_error_t *ra_svn_handle_textde
                                                   const apr_array_header_t *params,
                                                   ra_svn_driver_state_t *ds)
 {
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
   svn_string_t *str;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &token, &str));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ss", &token, &str));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (!entry->dstream)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -748,11 +765,11 @@ static svn_error_t *ra_svn_handle_textde
                                                 const apr_array_header_t *params,
                                                 ra_svn_driver_state_t *ds)
 {
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c", &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (!entry->dstream)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -768,11 +785,11 @@ static svn_error_t *ra_svn_handle_change
                                                    const apr_array_header_t *params,
                                                    ra_svn_driver_state_t *ds)
 {
-  const char *token, *name;
-  svn_string_t *value;
+  const char *name;
+  svn_string_t *token, *value;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc(?s)", &token, &name,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
                                   &value));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   SVN_CMD_ERR(ds->editor->change_file_prop(entry->baton, name, value, pool));
@@ -784,12 +801,12 @@ static svn_error_t *ra_svn_handle_close_
                                              const apr_array_header_t *params,
                                              ra_svn_driver_state_t *ds)
 {
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
   const char *text_checksum;
 
   /* Parse arguments and look up the file token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?c)",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
                                   &token, &text_checksum));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
 
@@ -807,11 +824,11 @@ static svn_error_t *ra_svn_handle_absent
                                               ra_svn_driver_state_t *ds)
 {
   const char *path;
-  const char *token;
+  svn_string_t *token;
   ra_svn_token_entry_t *entry;
 
   /* Parse parameters and look up the parent directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cc", &path, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Call the editor. */

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/marshal.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_ra_svn/marshal.c Wed Feb 11 13:29:26 2015
@@ -1433,7 +1433,7 @@ svn_ra_svn__parse_proplist(const apr_arr
                            apr_pool_t *pool,
                            apr_hash_t **props)
 {
-  char *name;
+  svn_string_t *name;
   svn_string_t *value;
   svn_ra_svn_item_t *elt;
   int i;
@@ -1445,9 +1445,9 @@ svn_ra_svn__parse_proplist(const apr_arr
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Proplist element not a list"));
-      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cs",
+      SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "ss",
                                       &name, &value));
-      svn_hash_sets(*props, name, value);
+      apr_hash_set(*props, name->data, name->len, value);
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_repos/log.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_repos/log.c Wed Feb 11 13:29:26 2015
@@ -1144,7 +1144,16 @@ fill_log_entry(svn_log_entry_t *log_entr
           int i;
 
           /* Requested only some revprops... */
-          
+
+          /* Make "svn:author" and "svn:date" available as svn_string_t
+             for efficient comparison via svn_string_compare().  Note that
+             we want static initialization here and must therefore emulate
+             strlen(x) by sizeof(x)-1. */
+          static const svn_string_t svn_prop_revision_author
+            = {SVN_PROP_REVISION_AUTHOR, sizeof(SVN_PROP_REVISION_AUTHOR)-1};
+          static const svn_string_t svn_prop_revision_date
+            = {SVN_PROP_REVISION_DATE, sizeof(SVN_PROP_REVISION_DATE)-1};
+
           /* often only the standard revprops got requested and delivered.
              In that case, we can simply pass the hash on. */
           if (revprops->nelts == apr_hash_count(r_props) && !censor_revprops)
@@ -1172,10 +1181,8 @@ fill_log_entry(svn_log_entry_t *log_entr
                 svn_string_t *value
                   = apr_hash_get(r_props, name->data, name->len);
                 if (censor_revprops
-                    && !(strncmp(name->data, SVN_PROP_REVISION_AUTHOR,
-                                 name->len) == 0
-                         || strncmp(name->data, SVN_PROP_REVISION_DATE,
-                                    name->len) == 0))
+                    && !svn_string_compare(name, &svn_prop_revision_author)
+                    && !svn_string_compare(name, &svn_prop_revision_date))
                   /* ... but we can only return author/date. */
                   continue;
                 if (log_entry->revprops == NULL)

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_repos/repos.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_repos/repos.c Wed Feb 11 13:29:26 2015
@@ -291,10 +291,76 @@ create_locks(svn_repos_t *repos, apr_poo
   "# For similar reasons, you should also add a trailing @ to URLs which"  NL \
   "# are passed to SVN commands accepting URLs with peg revisions."        NL
 
+/* Return template text for a hook script named SCRIPT_NAME. Include
+ * DESCRIPTION and SCRIPT in the template text.
+ */
+static const char *
+hook_template_text(const char *script_name,
+                   const char *description,
+                   const char *script,
+                   apr_pool_t *result_pool)
+{
+  return apr_pstrcat(result_pool,
+"#!/bin/sh"                                                                  NL
+""                                                                           NL,
+                     description,
+"#"                                                                          NL
+"# The default working directory for the invocation is undefined, so"        NL
+"# the program should set one explicitly if it cares."                       NL
+"#"                                                                          NL
+"# On a Unix system, the normal procedure is to have '", script_name, "'"    NL
+"# invoke other programs to do the real work, though it may do the"          NL
+"# work itself too."                                                         NL
+"#"                                                                          NL
+"# Note that '", script_name, "' must be executable by the user(s) who will" NL
+"# invoke it (typically the user httpd runs as), and that user must"         NL
+"# have filesystem-level permission to access the repository."               NL
+"#"                                                                          NL
+"# On a Windows system, you should name the hook program"                    NL
+"# '", script_name, ".bat' or '", script_name, ".exe',"                                                    NL
+"# but the basic idea is the same."                                          NL
+"#"                                                                          NL
+HOOKS_ENVIRONMENT_TEXT
+"#"                                                                          NL
+HOOKS_QUOTE_ARGUMENTS_TEXT
+"#"                                                                          NL
+"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
+PREWRITTEN_HOOKS_TEXT
+""                                                                           NL
+""                                                                           NL,
+                     script,
+                     SVN_VA_NULL);
+}
+
+/* Write a template file for a hook script named SCRIPT_NAME (appending
+ * '.tmpl' to that name) in REPOS. Include DESCRIPTION and SCRIPT in the
+ * template text.
+ */
+static svn_error_t *
+write_hook_template_file(svn_repos_t *repos, const char *script_name,
+                         const char *description,
+                         const char *script,
+                         apr_pool_t *pool)
+{
+  const char *template_path
+    = svn_dirent_join(repos->hook_path,
+                      apr_psprintf(pool, "%s%s",
+                                   script_name, SVN_REPOS__HOOK_DESC_EXT),
+                      pool);
+  const char *contents
+    = hook_template_text(script_name, description, script, pool);
+
+  SVN_ERR(svn_io_file_create(template_path, contents, pool));
+  SVN_ERR(svn_io_set_file_executable(template_path, TRUE, FALSE, pool));
+  return SVN_NO_ERROR;
+}
+
+/* Write the hook template files in REPOS.
+ */
 static svn_error_t *
 create_hooks(svn_repos_t *repos, apr_pool_t *pool)
 {
-  const char *this_path, *contents;
+  const char *description, *script;
 
   /* Create the hook directory. */
   SVN_ERR_W(create_repos_dir(repos->hook_path, pool),
@@ -303,16 +369,9 @@ create_hooks(svn_repos_t *repos, apr_poo
   /*** Write a default template for each standard hook file. */
 
   /* Start-commit hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_start_commit_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_START_COMMIT
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# START-COMMIT HOOK"                                                        NL
 "#"                                                                          NL
 "# The start-commit hook is invoked immediately after a Subversion txn is"   NL
@@ -343,33 +402,10 @@ create_hooks(svn_repos_t *repos, apr_poo
 "# make security assumptions based on the capabilities list, nor should"     NL
 "# you assume that clients reliably report every capability they have."      NL
 "#"                                                                          NL
-"# The working directory for this hook program's invocation is undefined,"   NL
-"# so the program should set one explicitly if it cares."                    NL
-"#"                                                                          NL
 "# If the hook program exits with success, the commit continues; but"        NL
 "# if it exits with failure (non-zero), the commit is stopped before"        NL
-"# a Subversion txn is created, and STDERR is returned to the client."       NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"# "                                                                         NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
+"# a Subversion txn is created, and STDERR is returned to the client."       NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "USER=\"$2\""                                                                NL
 ""                                                                           NL
@@ -379,25 +415,17 @@ PREWRITTEN_HOOKS_TEXT
 "# All checks passed, so allow the commit."                                  NL
 "exit 0"                                                                     NL;
 
-#undef SCRIPT_NAME
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating start-commit hook"));
 
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating start-commit hook"));
+#undef SCRIPT_NAME
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end start-commit hook */
 
   /* Pre-commit hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_pre_commit_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_PRE_COMMIT
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# PRE-COMMIT HOOK"                                                          NL
 "#"                                                                          NL
 "# The pre-commit hook is invoked before a Subversion txn is"                NL
@@ -419,18 +447,11 @@ PREWRITTEN_HOOKS_TEXT
 "#   by the separator character '|', followed by the lock token string,"     NL
 "#   followed by a newline."                                                 NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# If the hook program exits with success, the txn is committed; but"        NL
 "# if it exits with failure (non-zero), the txn is aborted, no commit"       NL
 "# takes place, and STDERR is returned to the client.   The hook"            NL
 "# program can use the 'svnlook' utility to help it examine the txn."        NL
 "#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
 "#   ***  NOTE: THE HOOK PROGRAM MUST NOT MODIFY THE TXN, EXCEPT  ***"       NL
 "#   ***  FOR REVISION PROPERTIES (like svn:log or svn:author).   ***"       NL
 "#"                                                                          NL
@@ -439,24 +460,8 @@ PREWRITTEN_HOOKS_TEXT
 "#   hooks should not modify the versioned data in txns, or else come"       NL
 "#   up with a mechanism to make it safe to do so (by informing the"         NL
 "#   committing client of the changes).  However, right now neither"         NL
-"#   mechanism is implemented, so hook writers just have to be careful."     NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"#"                                                                          NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
+"#   mechanism is implemented, so hook writers just have to be careful."     NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "TXN=\"$2\""                                                                 NL
 ""                                                                           NL
@@ -473,26 +478,17 @@ PREWRITTEN_HOOKS_TEXT
 "# All checks passed, so allow the commit."                                  NL
 "exit 0"                                                                     NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating pre-commit hook"));
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating pre-commit hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end pre-commit hook */
+#undef SCRIPT_NAME
 
 
   /* Pre-revprop-change hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_pre_revprop_change_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_PRE_REVPROP_CHANGE
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# PRE-REVPROP-CHANGE HOOK"                                                  NL
 "#"                                                                          NL
 "# The pre-revprop-change hook is invoked before a revision property"        NL
@@ -520,28 +516,8 @@ PREWRITTEN_HOOKS_TEXT
 "# will behave as if the hook were present, but failed.  The reason"         NL
 "# for this is that revision properties are UNVERSIONED, meaning that"       NL
 "# a successful propchange is destructive;  the old value is gone"           NL
-"# forever.  We recommend the hook back up the old value somewhere."         NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"#"                                                                          NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
+"# forever.  We recommend the hook back up the old value somewhere."         NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "REV=\"$2\""                                                                 NL
 "USER=\"$3\""                                                                NL
@@ -553,26 +529,17 @@ PREWRITTEN_HOOKS_TEXT
 "echo \"Changing revision properties other than svn:log is prohibited\" >&2" NL
 "exit 1"                                                                     NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating pre-revprop-change hook"));
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating pre-revprop-change hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end pre-revprop-change hook */
+#undef SCRIPT_NAME
 
 
   /* Pre-lock hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_pre_lock_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_PRE_LOCK
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# PRE-LOCK HOOK"                                                            NL
 "#"                                                                          NL
 "# The pre-lock hook is invoked before an exclusive lock is"                 NL
@@ -591,29 +558,10 @@ PREWRITTEN_HOOKS_TEXT
 "# this feature, you must guarantee the tokens generated are unique across"  NL
 "# the repository each time."                                                NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# If the hook program exits with success, the lock is created; but"         NL
 "# if it exits with failure (non-zero), the lock action is aborted"          NL
-"# and STDERR is returned to the client."                                    NL
-""                                                                           NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"#"                                                                          NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter:"          NL
-""                                                                           NL
+"# and STDERR is returned to the client."                                    NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "PATH=\"$2\""                                                                NL
 "USER=\"$3\""                                                                NL
@@ -647,26 +595,17 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "echo \"Error: $PATH already locked by ${LOCK_OWNER}.\" 1>&2"                NL
 "exit 1"                                                                     NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              "Creating pre-lock hook");
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating pre-lock hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end pre-lock hook */
+#undef SCRIPT_NAME
 
 
   /* Pre-unlock hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_pre_unlock_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_PRE_UNLOCK
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# PRE-UNLOCK HOOK"                                                          NL
 "#"                                                                          NL
 "# The pre-unlock hook is invoked before an exclusive lock is"               NL
@@ -680,29 +619,10 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "#   [4] TOKEN        (the lock token to be destroyed)"                      NL
 "#   [5] BREAK-UNLOCK (1 if the user is breaking the lock, else 0)"          NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# If the hook program exits with success, the lock is destroyed; but"       NL
 "# if it exits with failure (non-zero), the unlock action is aborted"        NL
-"# and STDERR is returned to the client."                                    NL
-""                                                                           NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"#"                                                                          NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter:"          NL
-""                                                                           NL
+"# and STDERR is returned to the client."                                    NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "PATH=\"$2\""                                                                NL
 "USER=\"$3\""                                                                NL
@@ -733,27 +653,17 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "echo \"Error: $PATH locked by ${LOCK_OWNER}.\" 1>&2"                        NL
 "exit 1"                                                                     NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              "Creating pre-unlock hook");
-
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  }  /* end pre-unlock hook */
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating pre-unlock hook"));
 
+#undef SCRIPT_NAME
 
 
   /* Post-commit hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_post_commit_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_POST_COMMIT
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# POST-COMMIT HOOK"                                                         NL
 "#"                                                                          NL
 "# The post-commit hook is invoked after a commit.  Subversion runs"         NL
@@ -765,60 +675,28 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "#   [2] REV          (the number of the revision just committed)"           NL
 "#   [3] TXN-NAME     (the name of the transaction that has become REV)"     NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# Because the commit has already completed and cannot be undone,"           NL
 "# the exit code of the hook program is ignored.  The hook program"          NL
 "# can use the 'svnlook' utility to help it examine the"                     NL
-"# newly-committed tree."                                                    NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"# "                                                                         NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
+"# newly-committed tree."                                                    NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "REV=\"$2\""                                                                 NL
 "TXN_NAME=\"$3\""                                                            NL
                                                                              NL
 "mailer.py commit \"$REPOS\" \"$REV\" /path/to/mailer.conf"                  NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating post-commit hook"));
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating post-commit hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  } /* end post-commit hook */
+#undef SCRIPT_NAME
 
 
   /* Post-lock hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_post_lock_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_POST_LOCK
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# POST-LOCK HOOK"                                                           NL
 "#"                                                                          NL
 "# The post-lock hook is run after a path is locked.  Subversion runs"       NL
@@ -831,57 +709,29 @@ PREWRITTEN_HOOKS_TEXT
 "#"                                                                          NL
 "# The paths that were just locked are passed to the hook via STDIN."        NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# Because the locks have already been created and cannot be undone,"        NL
 "# the exit code of the hook program is ignored.  The hook program"          NL
 "# can use the 'svnlook' utility to examine the paths in the repository"     NL
 "# but since the hook is invoked asyncronously the newly-created locks"      NL
-"# may no longer be present."                                                NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter:"          NL
-""                                                                           NL
+"# may no longer be present."                                                NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "USER=\"$2\""                                                                NL
 ""                                                                           NL
 "# Send email to interested parties, let them know a lock was created:"      NL
 "mailer.py lock \"$REPOS\" \"$USER\" /path/to/mailer.conf"                   NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              "Creating post-lock hook");
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating post-lock hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  } /* end post-lock hook */
+#undef SCRIPT_NAME
 
 
   /* Post-unlock hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_post_unlock_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_POST_UNLOCK
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# POST-UNLOCK HOOK"                                                         NL
 "#"                                                                          NL
 "# The post-unlock hook runs after a path is unlocked.  Subversion runs"     NL
@@ -894,54 +744,26 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "#"                                                                          NL
 "# The paths that were just unlocked are passed to the hook via STDIN."      NL
 "#"                                                                          NL
-"# The default working directory for the invocation is undefined, so"        NL
-"# the program should set one explicitly if it cares."                       NL
-"#"                                                                          NL
 "# Because the lock has already been destroyed and cannot be undone,"        NL
-"# the exit code of the hook program is ignored."                            NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter:"          NL
-""                                                                           NL
+"# the exit code of the hook program is ignored."                            NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "USER=\"$2\""                                                                NL
 ""                                                                           NL
 "# Send email to interested parties, let them know a lock was removed:"      NL
 "mailer.py unlock \"$REPOS\" \"$USER\" /path/to/mailer.conf"                 NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              "Creating post-unlock hook");
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating post-unlock hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  } /* end post-unlock hook */
+#undef SCRIPT_NAME
 
 
   /* Post-revprop-change hook. */
-  {
-    this_path = apr_psprintf(pool, "%s%s",
-                             svn_repos_post_revprop_change_hook(repos, pool),
-                             SVN_REPOS__HOOK_DESC_EXT);
-
 #define SCRIPT_NAME SVN_REPOS__HOOK_POST_REVPROP_CHANGE
 
-    contents =
-"#!/bin/sh"                                                                  NL
-""                                                                           NL
+  description =
 "# POST-REVPROP-CHANGE HOOK"                                                 NL
 "#"                                                                          NL
 "# The post-revprop-change hook is invoked after a revision property"        NL
@@ -961,28 +783,8 @@ HOOKS_QUOTE_ARGUMENTS_TEXT
 "# Because the propchange has already completed and cannot be undone,"       NL
 "# the exit code of the hook program is ignored.  The hook program"          NL
 "# can use the 'svnlook' utility to help it examine the"                     NL
-"# new property value."                                                      NL
-"#"                                                                          NL
-"# On a Unix system, the normal procedure is to have '"SCRIPT_NAME"'"        NL
-"# invoke other programs to do the real work, though it may do the"          NL
-"# work itself too."                                                         NL
-"#"                                                                          NL
-"# Note that '"SCRIPT_NAME"' must be executable by the user(s) who will"     NL
-"# invoke it (typically the user httpd runs as), and that user must"         NL
-"# have filesystem-level permission to access the repository."               NL
-"#"                                                                          NL
-"# On a Windows system, you should name the hook program"                    NL
-"# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
-"# but the basic idea is the same."                                          NL
-"# "                                                                         NL
-HOOKS_ENVIRONMENT_TEXT
-"# "                                                                         NL
-HOOKS_QUOTE_ARGUMENTS_TEXT
-"# "                                                                         NL
-"# Here is an example hook script, for a Unix /bin/sh interpreter."          NL
-PREWRITTEN_HOOKS_TEXT
-""                                                                           NL
-""                                                                           NL
+"# new property value."                                                      NL;
+  script =
 "REPOS=\"$1\""                                                               NL
 "REV=\"$2\""                                                                 NL
 "USER=\"$3\""                                                                NL
@@ -992,13 +794,11 @@ PREWRITTEN_HOOKS_TEXT
 "mailer.py propchange2 \"$REPOS\" \"$REV\" \"$USER\" \"$PROPNAME\" "
 "\"$ACTION\" /path/to/mailer.conf"                                           NL;
 
-#undef SCRIPT_NAME
-
-    SVN_ERR_W(svn_io_file_create(this_path, contents, pool),
-              _("Creating post-revprop-change hook"));
+  SVN_ERR_W(write_hook_template_file(repos, SCRIPT_NAME,
+                                     description, script, pool),
+            _("Creating post-revprop-change hook"));
 
-    SVN_ERR(svn_io_set_file_executable(this_path, TRUE, FALSE, pool));
-  } /* end post-revprop-change hook */
+#undef SCRIPT_NAME
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/auth.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_subr/auth.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/auth.c Wed Feb 11 13:29:26 2015
@@ -685,3 +685,167 @@ svn_auth_get_platform_specific_client_pr
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_auth__apply_config_for_server(svn_auth_baton_t *auth_baton,
+                                  apr_hash_t *config,
+                                  const char *server_name,
+                                  apr_pool_t *scratch_pool)
+{
+  svn_boolean_t store_passwords = SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
+  svn_boolean_t store_auth_creds = SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
+  const char *store_plaintext_passwords
+    = SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS;
+  svn_boolean_t store_pp = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP;
+  const char *store_pp_plaintext
+    = SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT;
+  svn_config_t *servers = NULL;
+  const char *server_group = NULL;
+
+  /* The 'store-passwords' and 'store-auth-creds' parameters used to
+  * live in SVN_CONFIG_CATEGORY_CONFIG. For backward compatibility,
+  * if values for these parameters have already been set by our
+  * callers, we use those values as defaults.
+  *
+  * Note that we can only catch the case where users explicitly set
+  * "store-passwords = no" or 'store-auth-creds = no".
+  *
+  * However, since the default value for both these options is
+  * currently (and has always been) "yes", users won't know
+  * the difference if they set "store-passwords = yes" or
+  * "store-auth-creds = yes" -- they'll get the expected behaviour.
+  */
+
+  if (svn_auth_get_parameter(auth_baton,
+                              SVN_AUTH_PARAM_DONT_STORE_PASSWORDS) != NULL)
+    store_passwords = FALSE;
+
+  if (svn_auth_get_parameter(auth_baton,
+                              SVN_AUTH_PARAM_NO_AUTH_CACHE) != NULL)
+    store_auth_creds = FALSE;
+
+  /* All the svn_auth_set_parameter() calls below this not only affect the
+     to be created ra session, but also all the ra sessions that are already
+     use this auth baton!
+
+     Please try to key things based on the realm string instead of this
+     construct.
+ */
+
+  if (config)
+    {
+      /* Grab the 'servers' config. */
+      servers = svn_hash_gets(config, SVN_CONFIG_CATEGORY_SERVERS);
+      if (servers)
+        {
+          /* First, look in the global section. */
+
+          SVN_ERR(svn_config_get_bool
+            (servers, &store_passwords, SVN_CONFIG_SECTION_GLOBAL,
+             SVN_CONFIG_OPTION_STORE_PASSWORDS,
+             store_passwords));
+
+          SVN_ERR(svn_config_get_yes_no_ask
+            (servers, &store_plaintext_passwords, SVN_CONFIG_SECTION_GLOBAL,
+             SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
+             SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
+
+          SVN_ERR(svn_config_get_bool
+            (servers, &store_pp, SVN_CONFIG_SECTION_GLOBAL,
+             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
+             store_pp));
+
+          SVN_ERR(svn_config_get_yes_no_ask
+            (servers, &store_pp_plaintext,
+             SVN_CONFIG_SECTION_GLOBAL,
+             SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
+             SVN_CONFIG_DEFAULT_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT));
+
+          SVN_ERR(svn_config_get_bool
+            (servers, &store_auth_creds, SVN_CONFIG_SECTION_GLOBAL,
+              SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+              store_auth_creds));
+
+          /* Find out where we're about to connect to, and
+           * try to pick a server group based on the destination. */
+          server_group = svn_config_find_group(servers, server_name,
+                                               SVN_CONFIG_SECTION_GROUPS,
+                                               scratch_pool);
+
+          if (server_group)
+            {
+              /* Override global auth caching parameters with the ones
+               * for the server group, if any. */
+              SVN_ERR(svn_config_get_bool(servers, &store_auth_creds,
+                                          server_group,
+                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
+                                          store_auth_creds));
+
+              SVN_ERR(svn_config_get_bool(servers, &store_passwords,
+                                          server_group,
+                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
+                                          store_passwords));
+
+              SVN_ERR(svn_config_get_yes_no_ask
+                (servers, &store_plaintext_passwords, server_group,
+                 SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
+                 store_plaintext_passwords));
+
+              SVN_ERR(svn_config_get_bool
+                (servers, &store_pp,
+                 server_group, SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP,
+                 store_pp));
+
+              SVN_ERR(svn_config_get_yes_no_ask
+                (servers, &store_pp_plaintext, server_group,
+                 SVN_CONFIG_OPTION_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
+                 store_pp_plaintext));
+            }
+        }
+    }
+
+  /* Save auth caching parameters in the auth parameter hash. */
+  if (! store_passwords)
+    svn_auth_set_parameter(auth_baton,
+                           SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
+
+  svn_auth_set_parameter(auth_baton,
+                         SVN_AUTH_PARAM_STORE_PLAINTEXT_PASSWORDS,
+                         store_plaintext_passwords);
+
+  if (! store_pp)
+    svn_auth_set_parameter(auth_baton,
+                           SVN_AUTH_PARAM_DONT_STORE_SSL_CLIENT_CERT_PP,
+                           "");
+
+  svn_auth_set_parameter(auth_baton,
+                         SVN_AUTH_PARAM_STORE_SSL_CLIENT_CERT_PP_PLAINTEXT,
+                         store_pp_plaintext);
+
+  if (! store_auth_creds)
+    svn_auth_set_parameter(auth_baton,
+                            SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
+
+  /* ### This setting may have huge side-effects when the auth baton is shared
+     ### between different ra sessions, as it will change which server settings
+     ### will be used for all future auth requests.
+     ###
+     ### E.g. when you connect using a ssl client cert that is specified in the
+     ### config file, you might have it when you first connect... but if you
+     ### then connect to another repository, you might not see the same
+     ### settings when the SSL connection is built up again later on.
+     ###
+     ### Most current usages should probably have been keyed on the realm
+     ### string instead of this magic flag that changes when multiple repositories
+     ### are used.
+     ###
+     ### This especially affects long living ra sessions, such as those on the
+     ### reuse-ra-session branch.
+   */
+  if (server_group)
+    svn_auth_set_parameter(auth_baton,
+                           SVN_AUTH_PARAM_SERVER_GROUP,
+                           apr_pstrdup(auth_baton->pool, server_group));
+
+  return SVN_NO_ERROR;
+}

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509.h
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509.h?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509.h (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509.h Wed Feb 11 13:29:26 2015
@@ -108,15 +108,19 @@ typedef struct _x509_cert {
 } x509_cert;
 
 
+struct svn_x509_name_attr_t {
+  unsigned char *oid;
+  apr_size_t oid_len;
+  const char *utf8_value;
+};
+
 /*
  * Certificate info, returned from the parser
  */
 struct svn_x509_certinfo_t
 {
-  apr_array_header_t *issuer_oids;
-  apr_hash_t *issuer;
-  apr_array_header_t *subject_oids;
-  apr_hash_t *subject;
+  apr_array_header_t *issuer;
+  apr_array_header_t *subject;
   apr_time_t valid_from;
   apr_time_t valid_to;
   svn_checksum_t *digest;

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509info.c Wed Feb 11 13:29:26 2015
@@ -34,6 +34,33 @@
 
 
 
+svn_x509_name_attr_t *
+svn_x509_name_attr_dup(const svn_x509_name_attr_t *attr,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
+{
+  svn_x509_name_attr_t *result = apr_palloc(result_pool, sizeof(*result));
+  result->oid_len = attr->oid_len;
+  result->oid = apr_palloc(result_pool, result->oid_len);
+  memcpy(result->oid, attr->oid, result->oid_len);
+  result->utf8_value = apr_pstrdup(result_pool, attr->utf8_value);
+
+  return result;
+}
+
+const unsigned char *
+svn_x509_name_attr_get_oid(const svn_x509_name_attr_t *attr, apr_size_t *len)
+{
+  *len = attr->oid_len;
+  return attr->oid;
+}
+
+const char *
+svn_x509_name_attr_get_value(const svn_x509_name_attr_t *attr)
+{
+  return attr->utf8_value;
+}
+
 /* Array elements are assumed to be nul-terminated C strings. */
 static apr_array_header_t *
 deep_copy_array(apr_array_header_t *s, apr_pool_t *result_pool)
@@ -56,31 +83,24 @@ deep_copy_array(apr_array_header_t *s, a
   return d;
 }
 
-/* Hash key and value are assumed to be nul-terminated C strings. */
-static apr_hash_t *deep_copy_hash(apr_hash_t *s,
-                                  apr_pool_t *scratch_pool, 
-                                  apr_pool_t *result_pool)
+/* Copy an array with elements that are svn_x509_name_attr_t's */
+static apr_array_header_t *
+deep_copy_name_attrs(apr_array_header_t *s, apr_pool_t *result_pool)
 {
-  apr_hash_t *d;
-  apr_hash_index_t *i;
+  int i;
+  apr_array_header_t *d;
 
   if (!s)
     return NULL;
 
-  d = apr_hash_make(result_pool);
-  i = apr_hash_first(scratch_pool, s);
+  d = apr_array_copy(result_pool, s);
 
-  /* Make a deep copy of the hash keys and values. */
-  while (i)
+  /* Make a deep copy of the svn_x509_name_attr_t's in the array. */
+  for (i = 0; i < s->nelts; ++i)
     {
-      const void *key;
-      void *val;
-      apr_ssize_t klen;
-
-      apr_hash_this(i, &key, &klen, &val);
-      apr_hash_set(d, apr_pstrndup(result_pool, key, klen), klen,
-                   apr_pstrdup(result_pool, val));
-      i = apr_hash_next(i);
+      APR_ARRAY_IDX(d, i, const svn_x509_name_attr_t *) =
+        svn_x509_name_attr_dup(APR_ARRAY_IDX(s, i, svn_x509_name_attr_t *),
+                               result_pool, result_pool);
     }
 
   return d;
@@ -92,10 +112,8 @@ svn_x509_certinfo_dup(const svn_x509_cer
                       apr_pool_t *scratch_pool)
 {
   svn_x509_certinfo_t *result = apr_palloc(result_pool, sizeof(*result));
-  result->subject_oids = deep_copy_array(certinfo->subject_oids, result_pool);
-  result->subject = deep_copy_hash(certinfo->subject, scratch_pool, result_pool);
-  result->issuer_oids = deep_copy_array(certinfo->issuer_oids, result_pool);
-  result->issuer = deep_copy_hash(certinfo->issuer, scratch_pool, result_pool);
+  result->subject = deep_copy_name_attrs(certinfo->subject, result_pool);
+  result->issuer = deep_copy_name_attrs(certinfo->issuer, result_pool);
   result->valid_from = certinfo->valid_from;
   result->valid_to = certinfo->valid_to;
   result->digest = svn_checksum_dup(certinfo->digest, result_pool);
@@ -105,49 +123,134 @@ svn_x509_certinfo_dup(const svn_x509_cer
 }
 
 typedef struct asn1_oid {
-  const char *oid_string;
+  const unsigned char *oid;
+  const ptrdiff_t oid_len;
   const char *short_label;
   const char *long_label;
 } asn1_oid;
 
+#define CONSTANT_PAIR(c) (unsigned char *)(c), sizeof((c)) - 1
+
 static const asn1_oid asn1_oids[] = {
-  { SVN_X509_OID_COMMON_NAME,  "CN", "commonName" },
-  { SVN_X509_OID_COUNTRY,      "C",  "countryName" },
-  { SVN_X509_OID_LOCALITY,     "L",  "localityName" },
-  { SVN_X509_OID_STATE,        "ST", "stateOrProvinceName" },
-  { SVN_X509_OID_ORGANIZATION, "O",  "organizationName" },
-  { SVN_X509_OID_ORG_UNIT,     "OU", "organizationalUnitName"},
-  { SVN_X509_OID_EMAIL,        NULL, "emailAddress" },
+  { CONSTANT_PAIR(SVN_X509_OID_COMMON_NAME),  "CN", "commonName" },
+  { CONSTANT_PAIR(SVN_X509_OID_COUNTRY),      "C",  "countryName" },
+  { CONSTANT_PAIR(SVN_X509_OID_LOCALITY),     "L",  "localityName" },
+  { CONSTANT_PAIR(SVN_X509_OID_STATE),        "ST", "stateOrProvinceName" },
+  { CONSTANT_PAIR(SVN_X509_OID_ORGANIZATION), "O",  "organizationName" },
+  { CONSTANT_PAIR(SVN_X509_OID_ORG_UNIT),     "OU", "organizationalUnitName"},
+  { CONSTANT_PAIR(SVN_X509_OID_EMAIL),        NULL, "emailAddress" },
   { NULL },
 };
 
-static const asn1_oid *oid_string_to_asn1_oid(const char *oid_string)
+/* Given an OID return a null-terminated C string representation.
+ * For example an OID with the bytes "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
+ * would be converted to the string "1.2.840.113549.1.9.1". */
+const char *
+svn_x509_oid_to_string(const unsigned char *oid, apr_size_t oid_len,
+                       apr_pool_t *scratch_pool, apr_pool_t *result_pool)
 {
-  const asn1_oid *oid;
+  svn_stringbuf_t *out = svn_stringbuf_create_empty(result_pool);
+  const unsigned char *p = oid;
+  const unsigned char *end = p + oid_len;
+  const char *temp;
+
+  while (p != end) {
+    if (p == oid)
+      {
+        /* Handle decoding the first two values of the OID.  These values
+         * are encoded by taking the first value and adding 40 to it and
+         * adding the result to the second value, then placing this single
+         * value in the first byte of the output.  This is unambiguous since
+         * the first value is apparently limited to 0, 1 or 2 and the second
+         * is limited to 0 to 39. */
+        temp = apr_psprintf(scratch_pool, "%d.%d", *p / 40, *p % 40);
+        p++;
+      }
+    else if (*p < 128)
+      {
+        /* The remaining values if they're less than 128 are just 
+         * the number one to one encoded */
+        temp = apr_psprintf(scratch_pool, ".%d", *p);
+        p++;
+      }
+    else
+      {
+        /* Values greater than 128 are encoded as a series of 7 bit values
+         * with the left most bit set to indicate this encoding with the
+         * last octet missing the left most bit to finish out the series.. */
+        unsigned int collector = 0;
+        svn_boolean_t dot = FALSE;
+
+        do {
+          if (collector == 0 && *p == 0x80)
+            {
+              /* include leading zeros in the string representation
+                 technically not legal, but this seems nicer than just
+                 returning NULL */
+              if (!dot)
+                {
+                  svn_stringbuf_appendbyte(out, '.');
+                  dot = TRUE;
+                }
+              svn_stringbuf_appendbyte(out, '0');
+            }
+          else if (collector > UINT_MAX >> 7)
+            {
+              /* overflow */
+              return NULL;
+            }
+          collector = collector << 7 | (*(p++) & 0x7f);
+        } while (p != end && *p > 127);
+        if (collector > UINT_MAX >> 7)
+          return NULL; /* overflow */
+        collector = collector << 7 | *(p++);
+        temp = apr_psprintf(scratch_pool, "%s%d", dot ? "" : ".", collector);
+      }
+    svn_stringbuf_appendcstr(out, temp);
+  }
 
-  for (oid = asn1_oids; oid->oid_string; oid++)
+  if (svn_stringbuf_isempty(out))
+    return NULL;
+
+  return out->data;
+}
+
+static const asn1_oid *oid_to_asn1_oid(unsigned char *oid, apr_size_t oid_len)
+{
+  const asn1_oid *entry;
+
+  for (entry = asn1_oids; entry->oid; entry++)
     {
-      if (strcmp(oid_string, oid->oid_string) == 0)
-        return oid;
+      if (oid_len == entry->oid_len &&
+          memcmp(oid, entry->oid, oid_len) == 0)
+        return entry;
     }
 
   return NULL;
 }
 
-static const char *oid_string_to_best_label(const char *oid_string)
+static const char *oid_to_best_label(unsigned char *oid, apr_size_t oid_len,
+                                     apr_pool_t *result_pool)
 {
-  const asn1_oid *oid = oid_string_to_asn1_oid(oid_string);
+  const asn1_oid *entry = oid_to_asn1_oid(oid, oid_len);
 
-  if (oid)
+  if (entry)
     {
-      if (oid->short_label)
-        return oid->short_label;
+      if (entry->short_label)
+        return entry->short_label;
 
-      if (oid->long_label)
-        return oid->long_label;
+      if (entry->long_label)
+        return entry->long_label;
+    }
+  else
+    {
+      const char *oid_string = svn_x509_oid_to_string(oid, oid_len,
+                                                      result_pool, result_pool);
+      if (oid_string)
+        return oid_string;
     }
 
-  return oid_string;
+  return "??";
 }
 
 /*
@@ -156,23 +259,22 @@ static const char *oid_string_to_best_la
  * If CN is not NULL, return any common name in CN
  */
 static const char *
-get_dn(apr_array_header_t *oids,
-       apr_hash_t *hash,
+get_dn(apr_array_header_t *name,
        apr_pool_t *result_pool)
 {
   svn_stringbuf_t *buf = svn_stringbuf_create_empty(result_pool);
   int n;
 
-  for (n = 0; n < oids->nelts; n++)
+  for (n = 0; n < name->nelts; n++)
     {
-      const char *field = APR_ARRAY_IDX(oids, n, const char *);
+      const svn_x509_name_attr_t *attr = APR_ARRAY_IDX(name, n, svn_x509_name_attr_t *);
 
       if (n > 0)
         svn_stringbuf_appendcstr(buf, ", ");
 
-      svn_stringbuf_appendcstr(buf, oid_string_to_best_label(field));
+      svn_stringbuf_appendcstr(buf, oid_to_best_label(attr->oid, attr->oid_len, result_pool));
       svn_stringbuf_appendbyte(buf, '=');
-      svn_stringbuf_appendcstr(buf, svn_hash_gets(hash, field));
+      svn_stringbuf_appendcstr(buf, attr->utf8_value);
     }
 
   return buf->data;
@@ -182,40 +284,26 @@ const char *
 svn_x509_certinfo_get_subject(const svn_x509_certinfo_t *certinfo,
                               apr_pool_t *result_pool)
 {
-  return get_dn(certinfo->subject_oids, certinfo->subject, result_pool);
+  return get_dn(certinfo->subject, result_pool);
 }
 
 const apr_array_header_t *
-svn_x509_certinfo_get_subject_oids(const svn_x509_certinfo_t *certinfo)
+svn_x509_certinfo_get_subject_attrs(const svn_x509_certinfo_t *certinfo)
 {
-  return certinfo->subject_oids;
-}
-
-const char *
-svn_x509_certinfo_get_subject_attr(const svn_x509_certinfo_t *certinfo,
-                                   const char *oid)
-{
-  return svn_hash_gets(certinfo->subject, oid);
+  return certinfo->subject;
 }
 
 const char *
 svn_x509_certinfo_get_issuer(const svn_x509_certinfo_t *certinfo,
                              apr_pool_t *result_pool)
 {
-  return get_dn(certinfo->issuer_oids, certinfo->issuer, result_pool);
+  return get_dn(certinfo->issuer, result_pool);
 }
 
 const apr_array_header_t *
-svn_x509_certinfo_get_issuer_oids(const svn_x509_certinfo_t *certinfo)
-{
-  return certinfo->issuer_oids;
-}
-
-const char *
-svn_x509_certinfo_get_issuer_attr(const svn_x509_certinfo_t *certinfo,
-                                  const char *oid)
+svn_x509_certinfo_get_issuer_attrs(const svn_x509_certinfo_t *certinfo)
 {
-  return svn_hash_gets(certinfo->issuer, oid);
+  return certinfo->issuer;
 }
 
 apr_time_t
@@ -241,3 +329,4 @@ svn_x509_certinfo_get_hostnames(const sv
 {
   return certinfo->hostnames;
 }
+

Modified: subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509parse.c
URL: http://svn.apache.org/viewvc/subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509parse.c?rev=1658954&r1=1658953&r2=1658954&view=diff
==============================================================================
--- subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509parse.c (original)
+++ subversion/branches/reuse-ra-session/subversion/libsvn_subr/x509parse.c Wed Feb 11 13:29:26 2015
@@ -903,90 +903,27 @@ x509name_to_utf8_string(const x509_name
   return nul_escape(utf8_string, result_pool);
 }
 
-/* Given an OID return a null-terminated C string representation in *RESULT.
- * For example an OID with the bytes "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
- * would be converted to the string "1.2.840.113549.1.9.1". */
 static svn_error_t *
-asn1_oid_to_string(const char **result, const x509_buf *oid,
-                   apr_pool_t *scratch_pool, apr_pool_t *result_pool)
-{
-  svn_stringbuf_t *out = svn_stringbuf_create_empty(result_pool);
-  const unsigned char *p = oid->p;
-  const unsigned char *end = p + oid->len;
-  const char *temp;
-
-  *result = NULL;
-
-  if (oid->tag != ASN1_OID)
-    return svn_error_create(SVN_ERR_ASN1_UNEXPECTED_TAG, NULL, NULL);
-
-  if (oid->len <= 0)
-    return svn_error_create(SVN_ERR_ASN1_OUT_OF_DATA, NULL, NULL);
-
-  while (p != end) {
-    if (p == oid->p)
-      {
-        /* Handle decoding the first two values of the OID.  These values
-         * are encoded by taking the first value and adding 40 to it and
-         * adding the result to the second value, then placing this single
-         * value in the first byte of the output.  This is unambiguous since
-         * the first value is apparently limited to 0, 1 or 2 and the second
-         * is limited to 0 to 39. */
-        temp = apr_psprintf(scratch_pool, "%d.%d", *p / 40, *p % 40);
-        p++;
-      }
-    else if (*p < 128)
-      {
-        /* The remaining values if they're less than 128 are just 
-         * the number one to one encoded */
-        temp = apr_psprintf(scratch_pool, ".%d", *p);
-        p++;
-      }
-    else
-      {
-        /* Values greater than 128 are encoded as a series of 7 bit values
-         * with the left most bit set to indicate this encoding with the
-         * last octet missing the left most bit to finish out the series.. */
-        int collector = 0;
-
-        do {
-          collector = collector << 7 | (*(p++) & 0x7f);
-        } while (p != end && *p > 127);
-        collector = collector << 7 | *(p++);
-        temp = apr_psprintf(scratch_pool, ".%d", collector);
-      }
-    svn_stringbuf_appendcstr(out, temp);
-  }
-
-  *result = out->data;
-  return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-x509_name_to_certinfo(apr_array_header_t **oids,
-                      apr_hash_t **hash,
+x509_name_to_certinfo(apr_array_header_t **result,
                       const x509_name *dn,
                       apr_pool_t *scratch_pool,
                       apr_pool_t *result_pool)
 {
   const x509_name *name = dn;
 
-  *oids = apr_array_make(result_pool, 6, sizeof(const char *));
-  *hash = apr_hash_make(result_pool);
+  *result = apr_array_make(result_pool, 6, sizeof(svn_x509_name_attr_t *));
 
   while (name != NULL) {
-    const char *oid_string;
-    const char *utf8_value;
+    svn_x509_name_attr_t *attr = apr_palloc(result_pool, sizeof(svn_x509_name_attr_t));
 
-    SVN_ERR(asn1_oid_to_string(&oid_string, &name->oid,
-                               scratch_pool, result_pool));
-    APR_ARRAY_PUSH(*oids, const char *) = oid_string;
-    utf8_value = x509name_to_utf8_string(name, result_pool);
-    if (utf8_value)
-      svn_hash_sets(*hash, oid_string, utf8_value);
-    else
+    attr->oid_len = name->oid.len;
+    attr->oid = apr_palloc(result_pool, attr->oid_len);
+    memcpy(attr->oid, name->oid.p, attr->oid_len);
+    attr->utf8_value = x509name_to_utf8_string(name, result_pool);
+    if (!attr->utf8_value)
       /* this should never happen */
-      svn_hash_sets(*hash, oid_string, "??");
+      attr->utf8_value = apr_pstrdup(result_pool, "??");
+    APR_ARRAY_PUSH(*result, const svn_x509_name_attr_t *) = attr;
 
     name = name->next;
   }
@@ -1028,6 +965,23 @@ is_hostname(const char *str)
   return TRUE;
 }
 
+static const char *
+x509parse_get_cn(apr_array_header_t *subject)
+{
+  int i;
+
+  for (i = 0; i < subject->nelts; ++i)
+    {
+      const svn_x509_name_attr_t *attr = APR_ARRAY_IDX(subject, i, const svn_x509_name_attr_t *);
+      if (equal(attr->oid, attr->oid_len,
+                SVN_X509_OID_COMMON_NAME, sizeof(SVN_X509_OID_COMMON_NAME) - 1))
+        return attr->utf8_value;
+    }
+
+  return NULL;
+}
+
+
 static void
 x509parse_get_hostnames(svn_x509_certinfo_t *ci, x509_cert *crt,
                         apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -1058,8 +1012,7 @@ x509parse_get_hostnames(svn_x509_certinf
       /* no SAN then get the hostname from the CommonName on the cert */
       const char *utf8_value;
 
-      utf8_value = svn_x509_certinfo_get_subject_attr(ci,
-                      SVN_X509_OID_COMMON_NAME);
+      utf8_value = x509parse_get_cn(ci->subject);
 
       if (utf8_value && is_hostname(utf8_value))
         {
@@ -1220,11 +1173,11 @@ svn_x509_parse_cert(svn_x509_certinfo_t
   ci = apr_pcalloc(result_pool, sizeof(*ci));
 
   /* Get the subject name */
-  SVN_ERR(x509_name_to_certinfo(&ci->subject_oids, &ci->subject, &crt->subject,
+  SVN_ERR(x509_name_to_certinfo(&ci->subject, &crt->subject,
                                 scratch_pool, result_pool));
 
   /* Get the issuer name */
-  SVN_ERR(x509_name_to_certinfo(&ci->issuer_oids, &ci->issuer, &crt->issuer,
+  SVN_ERR(x509_name_to_certinfo(&ci->issuer, &crt->issuer,
                                 scratch_pool, result_pool));
 
   /* Copy the validity range */



Mime
View raw message