static svn_error_t * test_read_only_mode(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; svn_config_t *cfg2; const char *cfg_file; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, FALSE, pool)); /* setting CFG to r/o mode shall toggle the r/o mode and expand values */ SVN_TEST_ASSERT(!svn_config__is_read_only(cfg)); SVN_TEST_ASSERT(!svn_config__is_expanded(cfg, "section1", "i")); svn_config__set_read_only(cfg, pool); SVN_TEST_ASSERT(svn_config__is_read_only(cfg)); SVN_TEST_ASSERT(svn_config__is_expanded(cfg, "section1", "i")); /* copies should be r/w with values */ SVN_ERR(svn_config_dup(&cfg2, cfg, pool)); SVN_TEST_ASSERT(!svn_config__is_read_only(cfg2)); return SVN_NO_ERROR; }
static svn_error_t * test_expand(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; const char *cfg_file, *val; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, FALSE, pool)); /* Get expanded "g" which requires expanding "c". */ svn_config_get(cfg, &val, "section1", "g", NULL); /* Get expanded "c". */ svn_config_get(cfg, &val, "section1", "c", NULL); /* With pool debugging enabled this ensures that the expanded value of "c" was not created in a temporary pool when expanding "g". */ SVN_TEST_STRING_ASSERT(val, "bar"); /* Get expanded "j" and "k" which have cyclic definitions. * They must return empty values. */ svn_config_get(cfg, &val, "section1", "j", NULL); SVN_TEST_STRING_ASSERT(val, ""); svn_config_get(cfg, &val, "section1", "k", NULL); SVN_TEST_STRING_ASSERT(val, ""); /* Get expanded "l" which depends on a cyclic definition. * So, it also considered "undefined" and will be normalized to "". */ svn_config_get(cfg, &val, "section1", "l", NULL); SVN_TEST_STRING_ASSERT(val, ""); return SVN_NO_ERROR; }
static svn_error_t * test_has_section_case_sensitive(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; const char *cfg_file; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, FALSE, pool)); if (! svn_config_has_section(cfg, "section1")) return fail(pool, "Failed to find section1"); if (svn_config_has_section(cfg, "SECTION1")) return fail(pool, "Returned true on missing section"); if (! svn_config_has_section(cfg, "UpperCaseSection")) return fail(pool, "Failed to find UpperCaseSection"); if (svn_config_has_section(cfg, "uppercasesection")) return fail(pool, "Returned true on missing section"); if (svn_config_has_section(cfg, "notthere")) return fail(pool, "Returned true on missing section"); return SVN_NO_ERROR; }
svn_error_t * svn_repos__parse_hooks_env(apr_hash_t **hooks_env_p, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { svn_config_t *cfg; struct parse_hooks_env_section_baton b; if (local_abspath) { SVN_ERR(svn_config_read3(&cfg, local_abspath, FALSE, TRUE, TRUE, scratch_pool)); b.cfg = cfg; b.hooks_env = apr_hash_make(result_pool); (void)svn_config_enumerate_sections2(cfg, parse_hooks_env_section, &b, scratch_pool); *hooks_env_p = b.hooks_env; } else { *hooks_env_p = NULL; } return SVN_NO_ERROR; }
svn_error_t * svn_repos__retrieve_config(svn_config_t **cfg_p, const char *path, svn_boolean_t must_exist, svn_boolean_t case_sensitive, apr_pool_t *pool) { if (svn_path_is_url(path)) { const char *dirent; svn_error_t *err; apr_pool_t *scratch_pool = svn_pool_create(pool); err = svn_uri_get_dirent_from_file_url(&dirent, path, scratch_pool); if (err == SVN_NO_ERROR) err = authz_retrieve_config_repo(cfg_p, dirent, must_exist, case_sensitive, pool, scratch_pool); /* Close the repos and streams we opened. */ svn_pool_destroy(scratch_pool); return err; } else { /* Outside of repo file or Windows registry*/ SVN_ERR(svn_config_read3(cfg_p, path, must_exist, case_sensitive, case_sensitive, pool)); } return SVN_NO_ERROR; }
static svn_error_t * test_memcache_basic(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_cache__t *cache; svn_config_t *config; svn_memcache_t *memcache = NULL; const char *prefix = apr_psprintf(pool, "test_memcache_basic-%" APR_TIME_T_FMT, apr_time_now()); if (opts->config_file) { SVN_ERR(svn_config_read3(&config, opts->config_file, TRUE, FALSE, FALSE, pool)); SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config, pool, pool)); } if (! memcache) return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, "not configured to use memcached"); /* Create a memcache-based cache. */ SVN_ERR(svn_cache__create_memcache(&cache, memcache, serialize_revnum, deserialize_revnum, APR_HASH_KEY_STRING, prefix, pool)); return basic_cache_test(cache, FALSE, pool); }
static svn_error_t * test_boolean_retrieval(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; int i; const char *cfg_file; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, FALSE, FALSE, pool)); for (i = 0; true_keys[i] != NULL; i++) { svn_boolean_t value; SVN_ERR(svn_config_get_bool(cfg, &value, "booleans", true_keys[i], FALSE)); if (!value) return fail(pool, "Value of option '%s' is not true", true_keys[i]); } for (i = 0; false_keys[i] != NULL; i++) { svn_boolean_t value; SVN_ERR(svn_config_get_bool(cfg, &value, "booleans", false_keys[i], TRUE)); if (value) return fail(pool, "Value of option '%s' is not true", false_keys[i]); } { svn_error_t *err; svn_boolean_t value; svn_error_clear((err = svn_config_get_bool(cfg, &value, "booleans", "bad_true", TRUE))); if (!err) return fail(pool, "No error on bad truth value"); svn_error_clear((err = svn_config_get_bool(cfg, &value, "booleans", "bad_false", FALSE))); if (!err) return fail(pool, "No error on bad truth value"); } { svn_boolean_t value; SVN_ERR(svn_config_get_server_setting_bool(cfg, &value, "server group", "setting", FALSE)); if (value) return svn_error_create(SVN_ERR_TEST_FAILED, SVN_NO_ERROR, "Expected a svn_config_get_server_setting_bool()" "to return FALSE, but it returned TRUE"); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__authz_read(svn_authz_t **authz_p, const char *path, const char *groups_path, svn_boolean_t must_exist, svn_boolean_t accept_urls, apr_pool_t *pool) { svn_authz_t *authz = apr_palloc(pool, sizeof(*authz)); /* Load the authz file */ if (accept_urls) SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, TRUE, pool)); else SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool)); if (groups_path) { svn_config_t *groups_cfg; svn_error_t *err; /* Load the groups file */ if (accept_urls) SVN_ERR(svn_repos__retrieve_config(&groups_cfg, groups_path, must_exist, TRUE, pool)); else SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist, TRUE, TRUE, pool)); /* Copy the groups from groups_cfg into authz. */ err = authz_copy_groups(authz, groups_cfg, pool); /* Add the paths to the error stack since the authz_copy_groups routine knows nothing about them. */ if (err != SVN_NO_ERROR) return svn_error_createf(err->apr_err, err, "Error reading authz file '%s' with " "groups file '%s':", path, groups_path); } /* Make sure there are no errors in the configuration. */ SVN_ERR(svn_repos__authz_validate(authz, pool)); *authz_p = authz; return SVN_NO_ERROR; }
static svn_error_t * test_memcache_long_key(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_cache__t *cache; svn_config_t *config; svn_memcache_t *memcache = NULL; svn_revnum_t fifty = 50, *answer; svn_boolean_t found = FALSE; const char *prefix = apr_psprintf(pool, "test_memcache_long_key-%" APR_TIME_T_FMT, apr_time_now()); static const char *long_key = "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 50 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 100 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 150 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 200 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 250 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 300 */ ; if (opts->config_file) { SVN_ERR(svn_config_read3(&config, opts->config_file, TRUE, FALSE, FALSE, pool)); SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config, pool, pool)); } if (! memcache) return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, "not configured to use memcached"); /* Create a memcache-based cache. */ SVN_ERR(svn_cache__create_memcache(&cache, memcache, serialize_revnum, deserialize_revnum, APR_HASH_KEY_STRING, prefix, pool)); SVN_ERR(svn_cache__set(cache, long_key, &fifty, pool)); SVN_ERR(svn_cache__get((void **) &answer, &found, cache, long_key, pool)); if (! found) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "cache failed to find entry for 'fifty'"); if (*answer != 50) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "expected 50 but found '%ld'", *answer); return SVN_NO_ERROR; }
svn_error_t * svn_config_merge(svn_config_t *cfg, const char *file, svn_boolean_t must_exist) { /* The original config hash shouldn't change if there's an error while reading the confguration, so read into a temporary table. ### We could use a tmp subpool for this, since merge_cfg is going to be tossed afterwards. Premature optimization, though? */ svn_config_t *merge_cfg; SVN_ERR(svn_config_read3(&merge_cfg, file, must_exist, cfg->section_names_case_sensitive, cfg->option_names_case_sensitive, cfg->pool)); /* Now copy the new options into the original table. */ for_each_option(merge_cfg, cfg, merge_cfg->pool, merge_callback); return SVN_NO_ERROR; }
static svn_error_t * test_text_retrieval(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; int i; const char *cfg_file; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, FALSE, FALSE, pool)); /* Test values retrieved from our ConfigParser instance against values retrieved using svn_config. */ for (i = 0; config_keys[i] != NULL; i++) { const char *key, *py_val, *c_val; key = config_keys[i]; py_val = config_values[i]; svn_config_get(cfg, &c_val, "section1", key, "default value"); #if 0 printf("Testing expected value '%s' against '%s' for " "option '%s'\n", py_val, c_val, key); #endif /* Fail iff one value is null, or the strings don't match. */ if ((c_val == NULL) != (py_val == NULL) || (c_val != NULL && py_val != NULL && strcmp(c_val, py_val) != 0)) return fail(pool, "Expected value '%s' not equal to '%s' for " "option '%s'", py_val, c_val, key); } { const char *value = svn_config_get_server_setting(cfg, "server group", "setting", "default"); if (value == NULL || strcmp(value, "default") != 0) return svn_error_create(SVN_ERR_TEST_FAILED, SVN_NO_ERROR, "Expected a svn_config_get_server_setting()" "to return 'default'"); } return SVN_NO_ERROR; }
static svn_error_t * test_has_option_case_sensitive(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; const char *cfg_file; apr_int64_t value; int i; static struct test_dataset { const char *option; apr_int64_t value; } const test_data[] = { { "a", 1 }, { "A", 2 }, { "B", 3 }, { "b", 4 } }; static const int test_data_size = sizeof(test_data)/sizeof(*test_data); SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, TRUE, pool)); for (i = 0; i < test_data_size; ++i) { SVN_ERR(svn_config_get_int64(cfg, &value, "case-sensitive-option", test_data[i].option, -1)); if (test_data[i].value != value) return fail(pool, apr_psprintf(pool, "case-sensitive-option.%s != %" APR_INT64_T_FMT" but %"APR_INT64_T_FMT, test_data[i].option, test_data[i].value, value)); } return SVN_NO_ERROR; }
static svn_error_t * test_expand(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_config_t *cfg; const char *cfg_file, *val; SVN_ERR(get_config_file_path(&cfg_file, opts, pool)); SVN_ERR(svn_config_read3(&cfg, cfg_file, TRUE, TRUE, FALSE, pool)); /* Get expanded "g" which requires expanding "c". */ svn_config_get(cfg, &val, "section1", "g", NULL); /* Get expanded "c". */ svn_config_get(cfg, &val, "section1", "c", NULL); /* With pool debugging enabled this ensures that the expanded value of "c" was not created in a temporary pool when expanding "g". */ SVN_TEST_STRING_ASSERT(val, "bar"); return SVN_NO_ERROR; }
/* Read various configuration sources into *CFGP, in this order, with * later reads overriding the results of earlier ones: * * 1. SYS_REGISTRY_PATH (only on Win32, but ignored if NULL) * * 2. SYS_FILE_PATH (everywhere, but ignored if NULL) * * 3. USR_REGISTRY_PATH (only on Win32, but ignored if NULL) * * 4. USR_FILE_PATH (everywhere, but ignored if NULL) * * Allocate *CFGP in POOL. Even if no configurations are read, * allocate an empty *CFGP. */ static svn_error_t * read_all(svn_config_t **cfgp, const char *sys_registry_path, const char *usr_registry_path, const char *sys_file_path, const char *usr_file_path, apr_pool_t *pool) { svn_boolean_t red_config = FALSE; /* "red" is the past tense of "read" */ /*** Read system-wide configurations first... ***/ #ifdef WIN32 if (sys_registry_path) { SVN_ERR(svn_config_read3(cfgp, sys_registry_path, FALSE, FALSE, FALSE, pool)); red_config = TRUE; } #endif /* WIN32 */ if (sys_file_path) { if (red_config) SVN_ERR(svn_config_merge(*cfgp, sys_file_path, FALSE)); else { SVN_ERR(svn_config_read3(cfgp, sys_file_path, FALSE, FALSE, FALSE, pool)); red_config = TRUE; } } /*** ...followed by per-user configurations. ***/ #ifdef WIN32 if (usr_registry_path) { if (red_config) SVN_ERR(svn_config_merge(*cfgp, usr_registry_path, FALSE)); else { SVN_ERR(svn_config_read3(cfgp, usr_registry_path, FALSE, FALSE, FALSE, pool)); red_config = TRUE; } } #endif /* WIN32 */ if (usr_file_path) { if (red_config) SVN_ERR(svn_config_merge(*cfgp, usr_file_path, FALSE)); else { SVN_ERR(svn_config_read3(cfgp, usr_file_path, FALSE, FALSE, FALSE, pool)); red_config = TRUE; } } if (! red_config) SVN_ERR(svn_config_create2(cfgp, FALSE, FALSE, pool)); return SVN_NO_ERROR; }