diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
commit | cf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch) | |
tree | da27775a2161723ef342e91af41a8b51fedef405 /subversion/libsvn_subr/config.c | |
parent | bb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff) | |
download | subversion-tarball-master.tar.gz |
subversion-1.9.7HEADsubversion-1.9.7master
Diffstat (limited to 'subversion/libsvn_subr/config.c')
-rw-r--r-- | subversion/libsvn_subr/config.c | 150 |
1 files changed, 104 insertions, 46 deletions
diff --git a/subversion/libsvn_subr/config.c b/subversion/libsvn_subr/config.c index cf97f0d..770d699 100644 --- a/subversion/libsvn_subr/config.c +++ b/subversion/libsvn_subr/config.c @@ -23,6 +23,8 @@ +#include <assert.h> + #define APR_WANT_STRFUNC #define APR_WANT_MEMFUNC #include <apr_want.h> @@ -36,6 +38,7 @@ #include "svn_private_config.h" #include "private/svn_dep_compat.h" +#include "private/svn_subr_private.h" @@ -92,6 +95,7 @@ svn_config_create2(svn_config_t **cfgp, cfg->tmp_value = svn_stringbuf_create_empty(result_pool); cfg->section_names_case_sensitive = section_names_case_sensitive; cfg->option_names_case_sensitive = option_names_case_sensitive; + cfg->read_only = FALSE; *cfgp = cfg; return SVN_NO_ERROR; @@ -188,7 +192,8 @@ read_all(svn_config_t **cfgp, #ifdef WIN32 if (sys_registry_path) { - SVN_ERR(svn_config_read2(cfgp, sys_registry_path, FALSE, FALSE, pool)); + SVN_ERR(svn_config_read3(cfgp, sys_registry_path, FALSE, FALSE, FALSE, + pool)); red_config = TRUE; } #endif /* WIN32 */ @@ -214,8 +219,8 @@ read_all(svn_config_t **cfgp, SVN_ERR(svn_config_merge(*cfgp, usr_registry_path, FALSE)); else { - SVN_ERR(svn_config_read2(cfgp, usr_registry_path, - FALSE, FALSE, pool)); + SVN_ERR(svn_config_read3(cfgp, usr_registry_path, + FALSE, FALSE, FALSE, pool)); red_config = TRUE; } } @@ -242,7 +247,7 @@ read_all(svn_config_t **cfgp, /* CONFIG_DIR provides an override for the default behavior of reading the default set of overlay files described by read_all()'s doc - string. */ + string. Returns non-NULL *CFG or an error. */ static svn_error_t * get_category_config(svn_config_t **cfg, const char *config_dir, @@ -259,9 +264,9 @@ get_category_config(svn_config_t **cfg, { #ifdef WIN32 sys_reg_path = apr_pstrcat(pool, SVN_REGISTRY_SYS_CONFIG_PATH, - category, NULL); + category, SVN_VA_NULL); usr_reg_path = apr_pstrcat(pool, SVN_REGISTRY_USR_CONFIG_PATH, - category, NULL); + category, SVN_VA_NULL); #endif /* WIN32 */ err = svn_config__sys_config_path(&sys_cfg_path, category, pool); @@ -291,19 +296,29 @@ svn_config_get_config(apr_hash_t **cfg_hash, svn_config_t *cfg; *cfg_hash = apr_hash_make(pool); -#define CATLEN (sizeof(SVN_CONFIG_CATEGORY_SERVERS) - 1) SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_SERVERS, pool)); - if (cfg) - apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_SERVERS, CATLEN, cfg); -#undef CATLEN + svn_hash_sets(*cfg_hash, SVN_CONFIG_CATEGORY_SERVERS, cfg); -#define CATLEN (sizeof(SVN_CONFIG_CATEGORY_CONFIG) - 1) SVN_ERR(get_category_config(&cfg, config_dir, SVN_CONFIG_CATEGORY_CONFIG, pool)); - if (cfg) - apr_hash_set(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, CATLEN, cfg); -#undef CATLEN + svn_hash_sets(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, cfg); + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_config__get_default_config(apr_hash_t **cfg_hash, + apr_pool_t *pool) +{ + svn_config_t *empty_cfg; + *cfg_hash = apr_hash_make(pool); + + SVN_ERR(svn_config_create2(&empty_cfg, FALSE, FALSE, pool)); + svn_hash_sets(*cfg_hash, SVN_CONFIG_CATEGORY_CONFIG, empty_cfg); + + SVN_ERR(svn_config_create2(&empty_cfg, FALSE, FALSE, pool)); + svn_hash_sets(*cfg_hash, SVN_CONFIG_CATEGORY_SERVERS, empty_cfg); return SVN_NO_ERROR; } @@ -415,6 +430,26 @@ make_hash_key(char *key) return key; } +/* Return the value for KEY in HASH. If CASE_SENSITIVE is FALSE, + BUFFER will be used to construct the normalized hash key. */ +static void * +get_hash_value(apr_hash_t *hash, + svn_stringbuf_t *buffer, + const char *key, + svn_boolean_t case_sensitive) +{ + apr_size_t i; + apr_size_t len = strlen(key); + + if (case_sensitive) + return apr_hash_get(hash, key, len); + + svn_stringbuf_ensure(buffer, len); + for (i = 0; i < len; ++i) + buffer->data[i] = (char)apr_tolower(key[i]); + + return apr_hash_get(hash, buffer->data, len); +} /* Return a pointer to an option in CFG, or NULL if it doesn't exist. if SECTIONP is non-null, return a pointer to the option's section. @@ -423,30 +458,16 @@ static cfg_option_t * find_option(svn_config_t *cfg, const char *section, const char *option, cfg_section_t **sectionp) { - void *sec_ptr; - - /* Canonicalize the hash key */ - svn_stringbuf_set(cfg->tmp_key, section); - if (! cfg->section_names_case_sensitive) - make_hash_key(cfg->tmp_key->data); - - sec_ptr = apr_hash_get(cfg->sections, cfg->tmp_key->data, - cfg->tmp_key->len); + void *sec_ptr = get_hash_value(cfg->sections, cfg->tmp_key, section, + cfg->section_names_case_sensitive); if (sectionp != NULL) *sectionp = sec_ptr; if (sec_ptr != NULL && option != NULL) { cfg_section_t *sec = sec_ptr; - cfg_option_t *opt; - - /* Canonicalize the option key */ - svn_stringbuf_set(cfg->tmp_key, option); - if (! cfg->option_names_case_sensitive) - make_hash_key(cfg->tmp_key->data); - - opt = apr_hash_get(sec->options, cfg->tmp_key->data, - cfg->tmp_key->len); + cfg_option_t *opt = get_hash_value(sec->options, cfg->tmp_key, option, + cfg->option_names_case_sensitive); /* NOTE: ConfigParser's sections are case sensitive. */ if (opt == NULL && apr_strnatcasecmp(section, SVN_CONFIG__DEFAULT_SECTION) != 0) @@ -482,7 +503,13 @@ make_string_from_option(const char **valuep, svn_config_t *cfg, */ if (opt->value && strchr(opt->value, '%')) { - apr_pool_t *tmp_pool = (x_pool ? x_pool : svn_pool_create(cfg->x_pool)); + apr_pool_t *tmp_pool; + + /* setting read-only mode should have expanded all values + * automatically. */ + assert(!cfg->read_only); + + tmp_pool = (x_pool ? x_pool : svn_pool_create(cfg->x_pool)); expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool); opt->expanded = TRUE; @@ -642,6 +669,33 @@ svn_config_create_option(cfg_option_t **opt, *opt = o; } +svn_boolean_t +svn_config__is_expanded(svn_config_t *cfg, + const char *section, + const char *option) +{ + cfg_option_t *opt; + + if (cfg == NULL) + return FALSE; + + /* does the option even exist? */ + opt = find_option(cfg, section, option, NULL); + if (opt == NULL) + return FALSE; + + /* already expanded? */ + if (opt->expanded) + return TRUE; + + /* needs expansion? */ + if (opt->value && strchr(opt->value, '%')) + return FALSE; + + /* no expansion necessary */ + return TRUE; +} + void svn_config_get(svn_config_t *cfg, const char **valuep, @@ -659,11 +713,11 @@ svn_config_get(svn_config_t *cfg, const char **valuep, } else /* before attempting to expand an option, check for the placeholder. - * If none is there, there is no point in calling expand_option_value. + * If there is none, there is no point in calling expand_option_value. */ if (default_value && strchr(default_value, '%')) { - apr_pool_t *tmp_pool = svn_pool_create(cfg->x_pool); + apr_pool_t *tmp_pool = svn_pool_create(cfg->pool); const char *x_default; expand_option_value(cfg, sec, default_value, &x_default, tmp_pool); if (x_default) @@ -686,6 +740,17 @@ svn_config_set(svn_config_t *cfg, cfg_section_t *sec; cfg_option_t *opt; + /* Ignore write attempts to r/o configurations. + * + * Since we should never try to modify r/o data, trigger an assertion + * in debug mode. + */ +#ifdef SVN_DEBUG + SVN_ERR_ASSERT_NO_RETURN(!cfg->read_only); +#endif + if (cfg->read_only) + return; + remove_expansions(cfg); opt = find_option(cfg, section, option, &sec); @@ -930,7 +995,7 @@ svn_config_enumerate(svn_config_t *cfg, const char *section, if (sec == NULL) return 0; - subpool = svn_pool_create(cfg->x_pool); + subpool = svn_pool_create(cfg->pool); count = 0; for (opt_ndx = apr_hash_first(subpool, sec->options); opt_ndx != NULL; @@ -1059,7 +1124,7 @@ svn_config_get_server_setting(svn_config_t *cfg, svn_error_t * svn_config_dup(svn_config_t **cfgp, - svn_config_t *src, + const svn_config_t *src, apr_pool_t *pool) { apr_hash_index_t *sectidx; @@ -1197,13 +1262,6 @@ svn_config_get_server_setting_bool(svn_config_t *cfg, svn_boolean_t svn_config_has_section(svn_config_t *cfg, const char *section) { - cfg_section_t *sec; - - /* Canonicalize the hash key */ - svn_stringbuf_set(cfg->tmp_key, section); - if (! cfg->section_names_case_sensitive) - make_hash_key(cfg->tmp_key->data); - - sec = svn_hash_gets(cfg->sections, cfg->tmp_key->data); - return sec != NULL; + return NULL != get_hash_value(cfg->sections, cfg->tmp_key, section, + cfg->section_names_case_sensitive); } |