Modified: subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/auth-cmd.c Mon Apr 13 13:27:51 2015 @@ -96,6 +96,39 @@ show_cert_failures(const char *failure_s return SVN_NO_ERROR; } + +/* decodes from format we store certs in for auth creds and + * turns parsing errors into warnings if PRINT_WARNING is TRUE + * and ignores them otherwise. returns NULL if it couldn't + * parse a cert for any reason. */ +static svn_x509_certinfo_t * +parse_certificate(const svn_string_t *ascii_cert, + svn_boolean_t print_warning, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_x509_certinfo_t *certinfo; + const svn_string_t *der_cert; + svn_error_t *err; + + /* Convert header-less PEM to DER by undoing base64 encoding. */ + der_cert = svn_base64_decode_string(ascii_cert, scratch_pool); + + err = svn_x509_parse_cert(&certinfo, der_cert->data, der_cert->len, + result_pool, scratch_pool); + if (err) + { + /* Just display X.509 parsing errors as warnings and continue */ + if (print_warning) + svn_handle_warning2(stderr, err, "svn: "); + svn_error_clear(err); + return NULL; + } + + return certinfo; +} + + struct walk_credentials_baton_t { int matches; @@ -115,12 +148,58 @@ match_pattern(const char *pattern, const return (apr_fnmatch(p, value, flags) == APR_SUCCESS); } +static svn_boolean_t +match_certificate(svn_x509_certinfo_t **certinfo, + const char *pattern, + const svn_string_t *ascii_cert, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + const char *value; + const svn_checksum_t *checksum; + const apr_array_header_t *hostnames; + int i; + + *certinfo = parse_certificate(ascii_cert, FALSE, result_pool, scratch_pool); + if (*certinfo == NULL) + return FALSE; + + value = svn_x509_certinfo_get_subject(*certinfo, scratch_pool); + if (match_pattern(pattern, value, FALSE, scratch_pool)) + return TRUE; + + value = svn_x509_certinfo_get_issuer(*certinfo, scratch_pool); + if (match_pattern(pattern, value, FALSE, scratch_pool)) + return TRUE; + + checksum = svn_x509_certinfo_get_digest(*certinfo); + value = svn_checksum_to_cstring_display(checksum, scratch_pool); + if (match_pattern(pattern, value, TRUE, scratch_pool)) + return TRUE; + + hostnames = svn_x509_certinfo_get_hostnames(*certinfo); + if (hostnames) + { + for (i = 0; i < hostnames->nelts; i++) + { + const char *hostname = APR_ARRAY_IDX(hostnames, i, const char *); + if (match_pattern(pattern, hostname, TRUE, scratch_pool)) + return TRUE; + } + } + + return FALSE; +} + + static svn_error_t * match_credential(svn_boolean_t *match, + svn_x509_certinfo_t **certinfo, const char *cred_kind, const char *realmstring, apr_array_header_t *patterns, apr_array_header_t *cred_items, + apr_pool_t *result_pool, apr_pool_t *scratch_pool) { int i; @@ -152,7 +231,8 @@ match_credential(svn_boolean_t *match, strcmp(key, SVN_CONFIG_AUTHN_PASSPHRASE_KEY) == 0) continue; /* don't match secrets */ else if (strcmp(key, SVN_CONFIG_AUTHN_ASCII_CERT_KEY) == 0) - continue; /* don't match base64 data */ + *match = match_certificate(certinfo, pattern, value, + result_pool, iterpool); else *match = match_pattern(pattern, value->data, FALSE, iterpool); @@ -168,25 +248,15 @@ match_credential(svn_boolean_t *match, } static svn_error_t * -show_cert(const svn_string_t *pem_cert, apr_pool_t *scratch_pool) +show_cert(svn_x509_certinfo_t *certinfo, const svn_string_t *pem_cert, + apr_pool_t *scratch_pool) { - const svn_string_t *der_cert; - svn_x509_certinfo_t *certinfo; const apr_array_header_t *hostnames; - svn_error_t *err; - /* Convert header-less PEM to DER by undoing base64 encoding. */ - der_cert = svn_base64_decode_string(pem_cert, scratch_pool); - - err = svn_x509_parse_cert(&certinfo, der_cert->data, der_cert->len, - scratch_pool, scratch_pool); - if (err) - { - /* Just display X.509 parsing errors as warnings and continue */ - svn_handle_warning2(stderr, err, "svn: "); - svn_error_clear(err); - return SVN_NO_ERROR; - } + if (certinfo == NULL) + certinfo = parse_certificate(pem_cert, TRUE, scratch_pool, scratch_pool); + if (certinfo == NULL) + return SVN_NO_ERROR; SVN_ERR(svn_cmdline_printf(scratch_pool, _("Subject: %s\n"), svn_x509_certinfo_get_subject(certinfo, scratch_pool))); @@ -229,6 +299,7 @@ list_credential(const char *cred_kind, const char *realmstring, apr_array_header_t *cred_items, svn_boolean_t show_passwords, + svn_x509_certinfo_t *certinfo, apr_pool_t *scratch_pool) { int i; @@ -275,7 +346,7 @@ list_credential(const char *cred_kind, else if (strcmp(key, SVN_CONFIG_AUTHN_USERNAME_KEY) == 0) SVN_ERR(svn_cmdline_printf(iterpool, _("Username: %s\n"), value->data)); else if (strcmp(key, SVN_CONFIG_AUTHN_ASCII_CERT_KEY) == 0) - SVN_ERR(show_cert(value, iterpool)); + SVN_ERR(show_cert(certinfo, value, iterpool)); else if (strcmp(key, SVN_CONFIG_AUTHN_FAILURES_KEY) == 0) SVN_ERR(show_cert_failures(value->data, iterpool)); else @@ -298,6 +369,7 @@ walk_credentials(svn_boolean_t *delete_c { struct walk_credentials_baton_t *b = baton; apr_array_header_t *sorted_cred_items; + svn_x509_certinfo_t *certinfo = NULL; *delete_cred = FALSE; @@ -308,9 +380,9 @@ walk_credentials(svn_boolean_t *delete_c { svn_boolean_t match; - SVN_ERR(match_credential(&match, cred_kind, realmstring, + SVN_ERR(match_credential(&match, &certinfo, cred_kind, realmstring, b->patterns, sorted_cred_items, - scratch_pool)); + scratch_pool, scratch_pool)); if (!match) return SVN_NO_ERROR; } @@ -319,7 +391,7 @@ walk_credentials(svn_boolean_t *delete_c if (b->list) SVN_ERR(list_credential(cred_kind, realmstring, sorted_cred_items, - b->show_passwords, scratch_pool)); + b->show_passwords, certinfo, scratch_pool)); if (b->delete) { *delete_cred = TRUE;
Modified: subversion/branches/move-tracking-2/subversion/svn/list-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/list-cmd.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/list-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/list-cmd.c Mon Apr 13 13:27:51 2015 @@ -49,6 +49,12 @@ struct print_baton { svn_boolean_t in_external; }; +/* Field flags required for this function */ +static const apr_uint32_t print_dirent_fields = SVN_DIRENT_KIND; +static const apr_uint32_t print_dirent_fields_verbose = ( + SVN_DIRENT_KIND | SVN_DIRENT_SIZE | SVN_DIRENT_TIME | + SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR); + /* This implements the svn_client_list_func2_t API, printing a single directory entry in text format. */ static svn_error_t * @@ -161,7 +167,10 @@ print_dirent(void *baton, } } - +/* Field flags required for this function */ +static const apr_uint32_t print_dirent_xml_fields = ( + SVN_DIRENT_KIND | SVN_DIRENT_SIZE | SVN_DIRENT_TIME | + SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR); /* This implements the svn_client_list_func2_t API, printing a single dirent in XML format. */ static svn_error_t * @@ -314,10 +323,12 @@ svn_cl__list(apr_getopt_t *os, "mode")); } - if (opt_state->verbose || opt_state->xml) - dirent_fields = SVN_DIRENT_ALL; + if (opt_state->xml) + dirent_fields = print_dirent_xml_fields; + else if (opt_state->verbose) + dirent_fields = print_dirent_fields_verbose; else - dirent_fields = SVN_DIRENT_KIND; /* the only thing we actually need... */ + dirent_fields = print_dirent_fields; pb.ctx = ctx; pb.verbose = opt_state->verbose; Modified: subversion/branches/move-tracking-2/subversion/svn/status-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/status-cmd.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svn/status-cmd.c (original) +++ subversion/branches/move-tracking-2/subversion/svn/status-cmd.c Mon Apr 13 13:27:51 2015 @@ -291,6 +291,10 @@ svn_cl__status(apr_getopt_t *os, /* We want our -u statuses to be against HEAD by default. */ if (opt_state->start_revision.kind == svn_opt_revision_unspecified) rev.kind = svn_opt_revision_head; + else if (! opt_state->update) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--revision (-r) option valid only with " + "--show-updates (-u) option")); else rev = opt_state->start_revision; Modified: subversion/branches/move-tracking-2/subversion/svnserve/serve.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnserve/serve.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/svnserve/serve.c (original) +++ subversion/branches/move-tracking-2/subversion/svnserve/serve.c Mon Apr 13 13:27:51 2015 @@ -1779,12 +1779,9 @@ static svn_error_t *get_dir(svn_ra_svn_c if (dirent_fields & SVN_DIRENT_HAS_PROPS) { - apr_hash_t *file_props; - /* has_props */ - SVN_CMD_ERR(svn_fs_node_proplist(&file_props, root, file_path, + SVN_CMD_ERR(svn_fs_node_has_props(&has_props, root, file_path, subpool)); - has_props = (apr_hash_count(file_props) > 0); } if ((dirent_fields & SVN_DIRENT_LAST_AUTHOR) Modified: subversion/branches/move-tracking-2/subversion/tests/cmdline/commit_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/cmdline/commit_tests.py?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/cmdline/commit_tests.py (original) +++ subversion/branches/move-tracking-2/subversion/tests/cmdline/commit_tests.py Mon Apr 13 13:27:51 2015 @@ -3087,6 +3087,32 @@ def mkdir_conflict_proper_error(sbox): 'mkdir', repo_url + '/A', '-m', '') +def commit_xml(sbox): + "commit an xml file" + + sbox.build() + + sbox.simple_add_text('index.xml', 'index.xml') + sbox.simple_add_text('index.html', 'index.html') + sbox.simple_propset('svn:mime-type', 'text/xml', 'index.xml') + sbox.simple_propset('svn:mime-type', 'text/html', 'index.html') + + # This currently (2015-04-09) makes mod_dav return a 'HTTP/1.1 201 Created' + # result with content type text/xml (copied from file), which used to + # invoke the error parsing. + # + # Depending on the Apache version and config, this may cause an xml error. + sbox.simple_commit() + + # This currently (2015-04-09) makes mod_dav return a 'HTTP/1.1 204 Updated' + # result with content type text/xml (copied from file), which used to + # invoke the error parsing. + # + # Depending on the Apache version and config, this may cause an xml error. + sbox.simple_append('index.xml', '<Q></R>', True) + sbox.simple_append('index.html', '<Q></R>', True) + sbox.simple_commit() + ######################################################################## # Run the tests @@ -3163,6 +3189,7 @@ test_list = [ None, commit_deep_deleted, commit_mergeinfo_ood, mkdir_conflict_proper_error, + commit_xml, ] if __name__ == '__main__': Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_ra/ra-test.c Mon Apr 13 13:27:51 2015 @@ -1440,6 +1440,83 @@ errors_from_callbacks(const svn_test_opt return SVN_NO_ERROR; } +static svn_error_t * +ra_list_has_props(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *ra_session; + const svn_delta_editor_t *editor; + apr_pool_t *iterpool = svn_pool_create(pool); + int i; + void *edit_baton; + const char *trunk_url; + + SVN_ERR(make_and_open_repos(&ra_session, "ra_list_has_props", + opts, pool)); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, iterpool)); + + /* Create initial layout*/ + { + void *root_baton; + void *dir_baton; + + SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton)); + SVN_ERR(editor->add_directory("trunk", root_baton, NULL, SVN_INVALID_REVNUM, + iterpool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, iterpool)); + SVN_ERR(editor->add_directory("tags", root_baton, NULL, SVN_INVALID_REVNUM, + iterpool, &dir_baton)); + SVN_ERR(editor->close_directory(dir_baton, iterpool)); + SVN_ERR(editor->close_directory(root_baton, iterpool)); + SVN_ERR(editor->close_edit(edit_baton, iterpool)); + } + + SVN_ERR(svn_ra_get_repos_root2(ra_session, &trunk_url, pool)); + trunk_url = svn_path_url_add_component2(trunk_url, "trunk", pool); + + /* Create a few tags. Using a value like 8000 will take too long for a normal + testrun, but produces more realistic problems */ + for (i = 0; i < 50; i++) + { + void *root_baton; + void *tags_baton; + void *dir_baton; + + svn_pool_clear(iterpool); + + SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton, + apr_hash_make(pool), NULL, + NULL, NULL, FALSE, iterpool)); + + SVN_ERR(editor->open_root(edit_baton, i+1, pool, &root_baton)); + SVN_ERR(editor->open_directory("tags", root_baton, i+1, iterpool, + &tags_baton)); + SVN_ERR(editor->add_directory(apr_psprintf(iterpool, "tags/T%05d", i+1), + tags_baton, trunk_url, 1, iterpool, + &dir_baton)); + + SVN_ERR(editor->close_directory(dir_baton, iterpool)); + SVN_ERR(editor->close_directory(tags_baton, iterpool)); + SVN_ERR(editor->close_directory(root_baton, iterpool)); + SVN_ERR(editor->close_edit(edit_baton, iterpool)); + } + + { + apr_hash_t *dirents; + svn_revnum_t fetched_rev; + apr_hash_t *props; + + SVN_ERR(svn_ra_get_dir2(ra_session, &dirents, &fetched_rev, &props, + "tags", SVN_INVALID_REVNUM, + SVN_DIRENT_ALL, pool)); + } + + return SVN_NO_ERROR; +} + /* The test table. */ @@ -1468,6 +1545,8 @@ static struct svn_test_descriptor_t test "check how ra functions handle bad revisions"), SVN_TEST_OPTS_PASS(errors_from_callbacks, "check how ra layers handle errors from callbacks"), + SVN_TEST_OPTS_PASS(ra_list_has_props, + "check list has_props performance"), SVN_TEST_NULL }; Modified: subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1673180&r1=1673179&r2=1673180&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c (original) +++ subversion/branches/move-tracking-2/subversion/tests/libsvn_wc/wc-queries-test.c Mon Apr 13 13:27:51 2015 @@ -927,6 +927,15 @@ test_schema_statistics(apr_pool_t *scrat "VALUES (1, '', '')", NULL, NULL, NULL)); + SQLITE_ERR( + sqlite3_exec(sdb, + "INSERT INTO EXTERNALS (wc_id, local_relpath," + " parent_relpath, repos_id," + " presence, kind, def_local_relpath," + " def_repos_relpath) " + "VALUES (1, 'subdir', '', 1, 'normal', 'dir', '', '')", + NULL, NULL, NULL)); + /* These are currently not necessary for query optimization, but it's better to tell Sqlite how we intend to use this table anyway */ SQLITE_ERR(
