Modified: subversion/branches/pin-externals/subversion/libsvn_subr/ssl_server_trust_providers.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/ssl_server_trust_providers.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_subr/ssl_server_trust_providers.c (original) +++ subversion/branches/pin-externals/subversion/libsvn_subr/ssl_server_trust_providers.c Tue Feb 3 22:51:18 2015 @@ -74,57 +74,13 @@ ssl_server_trust_file_first_credentials( if (failstr) SVN_ERR(svn_cstring_atoui(&last_failures, failstr->data)); + /* If the cert is trusted and there are no new failures, we + * accept it by clearing all failures. */ if (trusted_cert && - svn_string_compare(this_cert, trusted_cert)) + svn_string_compare(this_cert, trusted_cert) && + (*failures & ~last_failures) == 0) { - svn_boolean_t save_cert = FALSE; - - /* If the cert is trusted and there are no new failures, we - * accept it by clearing all failures. */ - if ((*failures & ~last_failures) == 0) - { - *failures = 0; - } - - /* If the on-disk cert info is lacking new-in-1.9 human-readable - info, add the info now and save the cert. */ - if (!svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_HOSTNAME_KEY)) - { - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_HOSTNAME_KEY, - svn_string_create(cert_info->hostname, pool)); - save_cert = TRUE; - } - if (!svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_FINGERPRINT_KEY)) - { - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_FINGERPRINT_KEY, - svn_string_create(cert_info->fingerprint, pool)); - save_cert = TRUE; - } - if (!svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_VALID_FROM_KEY)) - { - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_VALID_FROM_KEY, - svn_string_create(cert_info->valid_from, pool)); - save_cert = TRUE; - } - if (!svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_VALID_UNTIL_KEY)) - { - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_VALID_UNTIL_KEY, - svn_string_create(cert_info->valid_until, pool)); - save_cert = TRUE; - } - if (!svn_hash_gets(creds_hash, SVN_CONFIG_AUTHN_ISSUER_DN_KEY)) - { - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_ISSUER_DN_KEY, - svn_string_create(cert_info->issuer_dname, pool)); - save_cert = TRUE; - } - - if (save_cert) - SVN_ERR(svn_config_write_auth_data(creds_hash, - SVN_AUTH_CRED_SSL_SERVER_TRUST, - realmstring, - config_dir, - pool)); + *failures = 0; } } @@ -167,16 +123,6 @@ ssl_server_trust_file_save_credentials(s svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_FAILURES_KEY, svn_string_createf(pool, "%lu", (unsigned long)creds->accepted_failures)); - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_HOSTNAME_KEY, - svn_string_create(cert_info->hostname, pool)); - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_FINGERPRINT_KEY, - svn_string_create(cert_info->fingerprint, pool)); - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_VALID_FROM_KEY, - svn_string_create(cert_info->valid_from, pool)); - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_VALID_UNTIL_KEY, - svn_string_create(cert_info->valid_until, pool)); - svn_hash_sets(creds_hash, SVN_CONFIG_AUTHN_ISSUER_DN_KEY, - svn_string_create(cert_info->issuer_dname, pool)); SVN_ERR(svn_config_write_auth_data(creds_hash, SVN_AUTH_CRED_SSL_SERVER_TRUST,
Modified: subversion/branches/pin-externals/subversion/libsvn_subr/utf.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/utf.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_subr/utf.c (original) +++ subversion/branches/pin-externals/subversion/libsvn_subr/utf.c Tue Feb 3 22:51:18 2015 @@ -59,6 +59,12 @@ static const char *SVN_APR_UTF8_CHARSET static svn_mutex__t *xlate_handle_mutex = NULL; static svn_boolean_t assume_native_charset_is_utf8 = FALSE; +#if defined(WIN32) +typedef svn_subr__win32_xlate_t xlate_handle_t; +#else +typedef apr_xlate_t xlate_handle_t; +#endif + /* The xlate handle cache is a global hash table with linked lists of xlate * handles. In multi-threaded environments, a thread "borrows" an xlate * handle from the cache during a translation and puts it back afterwards. @@ -69,7 +75,7 @@ static svn_boolean_t assume_native_chars * is the number of simultanous handles in use for that key. */ typedef struct xlate_handle_node_t { - apr_xlate_t *handle; + xlate_handle_t *handle; /* FALSE if the handle is not valid, since its pool is being destroyed. */ svn_boolean_t valid; @@ -205,7 +211,7 @@ xlate_alloc_handle(xlate_handle_node_t * apr_pool_t *pool) { apr_status_t apr_err; - apr_xlate_t *handle; + xlate_handle_t *handle; const char *name; /* The error handling doesn't support the following cases, since we don't @@ -217,7 +223,7 @@ xlate_alloc_handle(xlate_handle_node_t * /* Try to create a handle. */ #if defined(WIN32) - apr_err = svn_subr__win32_xlate_open((win32_xlate_t **)&handle, topage, + apr_err = svn_subr__win32_xlate_open(&handle, topage, frompage, pool); name = "win32-xlate: "; #else @@ -486,9 +492,8 @@ convert_to_stringbuf(xlate_handle_node_t #ifdef WIN32 apr_status_t apr_err; - apr_err = svn_subr__win32_xlate_to_stringbuf((win32_xlate_t *) node->handle, - src_data, src_length, - dest, pool); + apr_err = svn_subr__win32_xlate_to_stringbuf(node->handle, src_data, + src_length, dest, pool); #else apr_size_t buflen = src_length * 2; apr_status_t apr_err; @@ -1016,6 +1021,161 @@ svn_utf_cstring_from_utf8_string(const c } +/* Insert the given UCS-4 VALUE into BUF at the given OFFSET. */ +static void +membuf_insert_ucs4(svn_membuf_t *buf, apr_size_t offset, apr_int32_t value) +{ + svn_membuf__resize(buf, (offset + 1) * sizeof(value)); + ((apr_int32_t*)buf->data)[offset] = value; +} + +/* TODO: Use compiler intrinsics for byte swaps. */ +#define SWAP_SHORT(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)) +#define SWAP_LONG(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \ + | (((x) >> 8) & 0xff00) | (((x) >> 24) & 0xff)) + +#define IS_UTF16_LEAD_SURROGATE(c) ((c) >= 0xd800 && (c) <= 0xdbff) +#define IS_UTF16_TRAIL_SURROGATE(c) ((c) >= 0xdc00 && (c) <= 0xdfff) + +svn_error_t * +svn_utf__utf16_to_utf8(const svn_string_t **result, + const apr_uint16_t *utf16str, + apr_size_t utf16len, + svn_boolean_t big_endian, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + static const apr_uint16_t endiancheck = 0xa55a; + const svn_boolean_t arch_big_endian = + (((const char*)&endiancheck)[sizeof(endiancheck) - 1] == '\x5a'); + const svn_boolean_t swap_order = (!big_endian != !arch_big_endian); + + apr_uint16_t lead_surrogate; + apr_size_t length; + apr_size_t offset; + svn_membuf_t ucs4buf; + svn_membuf_t resultbuf; + svn_string_t *res; + + if (utf16len == SVN_UTF__UNKNOWN_LENGTH) + { + const apr_uint16_t *endp = utf16str; + while (*endp++) + ; + utf16len = (endp - utf16str); + } + + svn_membuf__create(&ucs4buf, utf16len * sizeof(apr_int32_t), scratch_pool); + + for (lead_surrogate = 0, length = 0, offset = 0; + offset < utf16len; ++offset) + { + const apr_uint16_t code = + (swap_order ? SWAP_SHORT(utf16str[offset]) : utf16str[offset]); + + if (lead_surrogate) + { + if (IS_UTF16_TRAIL_SURROGATE(code)) + { + /* Combine the lead and trail currogates into a 32-bit code. */ + membuf_insert_ucs4(&ucs4buf, length++, + (0x010000 + + (((lead_surrogate & 0x03ff) << 10) + | (code & 0x03ff)))); + lead_surrogate = 0; + continue; + } + else + { + /* If we didn't find a surrogate pair, just dump the + lead surrogate into the stream. */ + membuf_insert_ucs4(&ucs4buf, length++, lead_surrogate); + lead_surrogate = 0; + } + } + + if ((offset + 1) < utf16len && IS_UTF16_LEAD_SURROGATE(code)) + { + /* Store a lead surrogate that is followed by at least one + code for the next iteration. */ + lead_surrogate = code; + continue; + } + else + membuf_insert_ucs4(&ucs4buf, length++, code); + } + + /* Convert the UCS-4 buffer to UTF-8, assuming an average of 2 bytes + per code point for encoding. The buffer will grow as + necessary. */ + svn_membuf__create(&resultbuf, length * 2, result_pool); + SVN_ERR(svn_utf__encode_ucs4_string( + &resultbuf, ucs4buf.data, length, &length)); + + res = apr_palloc(result_pool, sizeof(*res)); + res->data = resultbuf.data; + res->len = length; + *result = res; + return SVN_NO_ERROR; +} + + +svn_error_t * +svn_utf__utf32_to_utf8(const svn_string_t **result, + const apr_int32_t *utf32str, + apr_size_t utf32len, + svn_boolean_t big_endian, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + static const apr_int32_t endiancheck = 0xa5cbbc5a; + const svn_boolean_t arch_big_endian = + (((const char*)&endiancheck)[sizeof(endiancheck) - 1] == '\x5a'); + const svn_boolean_t swap_order = (!big_endian != !arch_big_endian); + + apr_size_t length; + svn_membuf_t resultbuf; + svn_string_t *res; + + if (utf32len == SVN_UTF__UNKNOWN_LENGTH) + { + const apr_int32_t *endp = utf32str; + while (*endp++) + ; + utf32len = (endp - utf32str); + } + + if (swap_order) + { + apr_size_t offset; + svn_membuf_t ucs4buf; + + svn_membuf__create(&ucs4buf, utf32len * sizeof(apr_int32_t), + scratch_pool); + + for (offset = 0; offset < utf32len; ++offset) + { + const apr_int32_t code = SWAP_LONG(utf32str[offset]); + membuf_insert_ucs4(&ucs4buf, offset, code); + } + utf32str = ucs4buf.data; + } + + /* Convert the UCS-4 buffer to UTF-8, assuming an average of 2 bytes + per code point for encoding. The buffer will grow as + necessary. */ + svn_membuf__create(&resultbuf, utf32len * 2, result_pool); + SVN_ERR(svn_utf__encode_ucs4_string( + &resultbuf, utf32str, utf32len, &length)); + + res = apr_palloc(result_pool, sizeof(*res)); + res->data = resultbuf.data; + res->len = length; + *result = res; + return SVN_NO_ERROR; +} + + #ifdef WIN32 Modified: subversion/branches/pin-externals/subversion/libsvn_subr/utf8proc.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/utf8proc.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_subr/utf8proc.c (original) +++ subversion/branches/pin-externals/subversion/libsvn_subr/utf8proc.c Tue Feb 3 22:51:18 2015 @@ -218,20 +218,14 @@ encode_ucs4(svn_membuf_t *buffer, apr_in return SVN_NO_ERROR; } -/* Decode an UCS-4 string to UTF-8, placing the result into BUFFER. - * While utf8proc does have a similar function, it does more checking - * and processing than we want here. Return the length of the result - * (excluding the NUL terminator) in *result_length. - * - * A returned error indicates that the codepoint is invalid. - */ -static svn_error_t * -encode_ucs4_string(svn_membuf_t *buffer, - apr_int32_t *ucs4str, apr_size_t len, - apr_size_t *result_length) +svn_error_t * +svn_utf__encode_ucs4_string(svn_membuf_t *buffer, + const apr_int32_t *ucs4str, + apr_size_t length, + apr_size_t *result_length) { *result_length = 0; - while (len-- > 0) + while (length-- > 0) SVN_ERR(encode_ucs4(buffer, *ucs4str++, result_length)); svn_membuf__resize(buffer, *result_length + 1); ((char*)buffer->data)[*result_length] = '\0'; @@ -262,8 +256,8 @@ svn_utf__glob(svn_boolean_t *match, because apr_fnmatch can't handle it.*/ SVN_ERR(decompose_normalized(&tempbuf_len, pattern, pattern_len, temp_buf)); if (!sql_like) - SVN_ERR(encode_ucs4_string(pattern_buf, temp_buf->data, tempbuf_len, - &patternbuf_len)); + SVN_ERR(svn_utf__encode_ucs4_string(pattern_buf, temp_buf->data, + tempbuf_len, &patternbuf_len)); else { /* Convert a LIKE pattern to a GLOB pattern that apr_fnmatch can use. */ @@ -338,8 +332,8 @@ svn_utf__glob(svn_boolean_t *match, /* Now normalize the string */ SVN_ERR(decompose_normalized(&tempbuf_len, string, string_len, temp_buf)); - SVN_ERR(encode_ucs4_string(string_buf, temp_buf->data, - tempbuf_len, &tempbuf_len)); + SVN_ERR(svn_utf__encode_ucs4_string(string_buf, temp_buf->data, + tempbuf_len, &tempbuf_len)); *match = !apr_fnmatch(pattern_buf->data, string_buf->data, 0); return SVN_NO_ERROR; Modified: subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.c (original) +++ subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.c Tue Feb 3 22:51:18 2015 @@ -77,11 +77,11 @@ initialize_com(void *baton, apr_pool_t* return SVN_NO_ERROR; } -typedef struct win32_xlate_t +struct svn_subr__win32_xlate_t { UINT from_page_id; UINT to_page_id; -} win32_xlate_t; +}; static apr_status_t get_page_id_from_name(UINT *page_id_p, const char *page_name, apr_pool_t *pool) @@ -166,12 +166,12 @@ get_page_id_from_name(UINT *page_id_p, c } apr_status_t -svn_subr__win32_xlate_open(win32_xlate_t **xlate_p, const char *topage, +svn_subr__win32_xlate_open(svn_subr__win32_xlate_t **xlate_p, const char *topage, const char *frompage, apr_pool_t *pool) { UINT from_page_id, to_page_id; apr_status_t apr_err = APR_SUCCESS; - win32_xlate_t *xlate; + svn_subr__win32_xlate_t *xlate; apr_err = get_page_id_from_name(&to_page_id, topage, pool); if (apr_err == APR_SUCCESS) @@ -190,7 +190,7 @@ svn_subr__win32_xlate_open(win32_xlate_t } apr_status_t -svn_subr__win32_xlate_to_stringbuf(win32_xlate_t *handle, +svn_subr__win32_xlate_to_stringbuf(svn_subr__win32_xlate_t *handle, const char *src_data, apr_size_t src_length, svn_stringbuf_t **dest, Modified: subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.h URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.h?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.h (original) +++ subversion/branches/pin-externals/subversion/libsvn_subr/win32_xlate.h Tue Feb 3 22:51:18 2015 @@ -27,25 +27,27 @@ #ifdef WIN32 /* Opaque translation buffer. */ -typedef struct win32_xlate_t win32_xlate_t; +typedef struct svn_subr__win32_xlate_t svn_subr__win32_xlate_t; /* Set *XLATE_P to a handle node for converting from FROMPAGE to TOPAGE. Returns APR_EINVAL or APR_ENOTIMPL, if a conversion isn't supported. If fail for any other reason, return the error. Allocate *RET in POOL. */ -apr_status_t svn_subr__win32_xlate_open(win32_xlate_t **xlate_p, - const char *topage, - const char *frompage, - apr_pool_t *pool); +apr_status_t +svn_subr__win32_xlate_open(svn_subr__win32_xlate_t **xlate_p, + const char *topage, + const char *frompage, + apr_pool_t *pool); /* Convert SRC_LENGTH bytes of SRC_DATA in NODE->handle, store the result in *DEST, which is allocated in POOL. */ -apr_status_t svn_subr__win32_xlate_to_stringbuf(win32_xlate_t *handle, - const char *src_data, - apr_size_t src_length, - svn_stringbuf_t **dest, - apr_pool_t *pool); +apr_status_t +svn_subr__win32_xlate_to_stringbuf(svn_subr__win32_xlate_t *handle, + const char *src_data, + apr_size_t src_length, + svn_stringbuf_t **dest, + apr_pool_t *pool); #endif /* WIN32 */ Modified: subversion/branches/pin-externals/subversion/svn/auth-cmd.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svn/auth-cmd.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/svn/auth-cmd.c (original) +++ subversion/branches/pin-externals/subversion/svn/auth-cmd.c Tue Feb 3 22:51:18 2015 @@ -41,6 +41,9 @@ #include "svn_config.h" #include "svn_auth.h" #include "svn_sorts.h" +#include "svn_base64.h" +#include "svn_x509.h" +#include "svn_time.h" #include "private/svn_cmdline_private.h" #include "private/svn_token.h" @@ -150,9 +153,6 @@ match_credential(svn_boolean_t *match, continue; /* don't match secrets */ else if (strcmp(key, SVN_CONFIG_AUTHN_ASCII_CERT_KEY) == 0) continue; /* don't match base64 data */ - else if (strcmp(key, SVN_CONFIG_AUTHN_HOSTNAME_KEY) == 0 || - strcmp(key, SVN_CONFIG_AUTHN_FINGERPRINT_KEY) == 0) - *match = match_pattern(pattern, value->data, TRUE, iterpool); else *match = match_pattern(pattern, value->data, FALSE, iterpool); @@ -168,6 +168,63 @@ match_credential(svn_boolean_t *match, } static svn_error_t * +show_cert(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; + } + + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Subject: %s\n"), + svn_x509_certinfo_get_subject(certinfo, scratch_pool))); + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Valid from: %s\n"), + svn_time_to_human_cstring( + svn_x509_certinfo_get_valid_from(certinfo), + scratch_pool))); + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Valid until: %s\n"), + svn_time_to_human_cstring( + svn_x509_certinfo_get_valid_to(certinfo), + scratch_pool))); + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Issuer: %s\n"), + svn_x509_certinfo_get_issuer(certinfo, scratch_pool))); + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Fingerprint: %s\n"), + svn_checksum_to_cstring_display( + svn_x509_certinfo_get_digest(certinfo), + scratch_pool))); + + hostnames = svn_x509_certinfo_get_hostnames(certinfo); + if (hostnames && !apr_is_empty_array(hostnames)) + { + int i; + svn_stringbuf_t *buf = svn_stringbuf_create_empty(scratch_pool); + for (i = 0; i < hostnames->nelts; ++i) + { + const char *hostname = APR_ARRAY_IDX(hostnames, i, const char*); + if (i > 0) + svn_stringbuf_appendbytes(buf, ", ", 2); + svn_stringbuf_appendbytes(buf, hostname, strlen(hostname)); + } + SVN_ERR(svn_cmdline_printf(scratch_pool, _("Hostnames: %s\n"), + buf->data)); + } + + return SVN_NO_ERROR; +} + +static svn_error_t * list_credential(const char *cred_kind, const char *realmstring, apr_array_header_t *cred_items, @@ -188,7 +245,7 @@ list_credential(const char *cred_kind, svn_sort__item_t item; const char *key; svn_string_t *value; - + svn_pool_clear(iterpool); item = APR_ARRAY_IDX(cred_items, i, svn_sort__item_t); key = item.key; @@ -218,20 +275,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) - continue; /* don't show data which is not human-readable */ - else if (strcmp(key, SVN_CONFIG_AUTHN_HOSTNAME_KEY) == 0) - SVN_ERR(svn_cmdline_printf(iterpool, _("Hostname: %s\n"), value->data)); - else if (strcmp(key, SVN_CONFIG_AUTHN_VALID_FROM_KEY) == 0) - SVN_ERR(svn_cmdline_printf(iterpool, _("Valid from: %s\n"), - value->data)); - else if (strcmp(key, SVN_CONFIG_AUTHN_VALID_UNTIL_KEY) == 0) - SVN_ERR(svn_cmdline_printf(iterpool, _("Valid until: %s\n"), - value->data)); - else if (strcmp(key, SVN_CONFIG_AUTHN_ISSUER_DN_KEY) == 0) - SVN_ERR(svn_cmdline_printf(iterpool, _("Issuer: %s\n"), value->data)); - else if (strcmp(key, SVN_CONFIG_AUTHN_FINGERPRINT_KEY) == 0) - SVN_ERR(svn_cmdline_printf(iterpool, _("Fingerprint: %s\n"), - value->data)); + SVN_ERR(show_cert(value, iterpool)); else if (strcmp(key, SVN_CONFIG_AUTHN_FAILURES_KEY) == 0) SVN_ERR(show_cert_failures(value->data, iterpool)); else Modified: subversion/branches/pin-externals/subversion/svn/svn.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svn/svn.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/svn/svn.c (original) +++ subversion/branches/pin-externals/subversion/svn/svn.c Tue Feb 3 22:51:18 2015 @@ -1306,7 +1306,9 @@ const svn_opt_subcommand_desc2_t svn_cl_ "\n" " 1. Removes versioned props in working copy.\n" " 2. Removes unversioned remote prop on repos revision.\n" - " TARGET only determines which repository to access.\n"), + " TARGET only determines which repository to access.\n" + "\n" + " See 'svn help propset' for descriptions of the svn:* special properties.\n"), {'q', 'R', opt_depth, 'r', opt_revprop, opt_changelist} }, { "propedit", svn_cl__propedit, {"pedit", "pe"}, N_ @@ -1318,7 +1320,7 @@ const svn_opt_subcommand_desc2_t svn_cl_ " 2. Edits unversioned remote prop on repos revision.\n" " TARGET only determines which repository to access.\n" "\n" - " See 'svn help propset' for more on setting properties.\n"), + " See 'svn help propset' for descriptions of the svn:* special properties.\n"), {'r', opt_revprop, SVN_CL__LOG_MSG_OPTIONS, opt_force} }, { "propget", svn_cl__propget, {"pget", "pg"}, N_ @@ -1339,7 +1341,9 @@ const svn_opt_subcommand_desc2_t svn_cl_ " By default, an extra newline is printed after the property value so that\n" " the output looks pretty. With a single TARGET, depth 'empty' and without\n" " --show-inherited-props, you can use the --strict option to disable this\n" - " (useful when redirecting a binary property value to a file, for example).\n"), + " (useful when redirecting a binary property value to a file, for example).\n" + "\n" + " See 'svn help propset' for descriptions of the svn:* special properties.\n"), {'v', 'R', opt_depth, 'r', opt_revprop, opt_strict, opt_xml, opt_changelist, opt_show_inherited_props }, {{'v', N_("print path, name and value on separate lines")}, @@ -1356,7 +1360,9 @@ const svn_opt_subcommand_desc2_t svn_cl_ " TARGET only determines which repository to access.\n" "\n" " With --verbose, the property values are printed as well, like 'svn propget\n" - " --verbose'. With --quiet, the paths are not printed.\n"), + " --verbose'. With --quiet, the paths are not printed.\n" + "\n" + " See 'svn help propset' for descriptions of the svn:* special properties.\n"), {'v', 'R', opt_depth, 'r', 'q', opt_revprop, opt_xml, opt_changelist, opt_show_inherited_props }, {{'v', N_("print path, name and value on separate lines")}, Modified: subversion/branches/pin-externals/subversion/svnserve/serve.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svnserve/serve.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/svnserve/serve.c (original) +++ subversion/branches/pin-externals/subversion/svnserve/serve.c Tue Feb 3 22:51:18 2015 @@ -1725,6 +1725,11 @@ static svn_error_t *get_dir(svn_ra_svn_c &ab, root, full_path, pool)); + /* Fetch the directories' entries before starting the response, to allow + proper error handling in cases like when FULL_PATH doesn't exist */ + if (want_contents) + SVN_CMD_ERR(svn_fs_dir_entries(&entries, root, full_path, pool)); + /* Begin response ... */ SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "w(r(!", "success", rev)); SVN_ERR(svn_ra_svn__write_proplist(conn, pool, props)); @@ -1736,8 +1741,6 @@ static svn_error_t *get_dir(svn_ra_svn_c /* Use epoch for a placeholder for a missing date. */ const char *missing_date = svn_time_to_cstring(0, pool); - SVN_CMD_ERR(svn_fs_dir_entries(&entries, root, full_path, pool)); - /* Transform the hash table's FS entries into dirents. This probably * belongs in libsvn_repos. */ subpool = svn_pool_create(pool); Modified: subversion/branches/pin-externals/subversion/svnsync/sync.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svnsync/sync.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/svnsync/sync.c (original) +++ subversion/branches/pin-externals/subversion/svnsync/sync.c Tue Feb 3 22:51:18 2015 @@ -158,6 +158,12 @@ remove_r0_mergeinfo(const svn_string_t * svn_stringbuf_appendbytes(new_str, line, colon + 1 - line); svn_stringbuf_appendcstr(new_str, rangelist); } + else + { + if (new_str->len) + svn_stringbuf_appendbyte(new_str, '\n'); + svn_stringbuf_appendcstr(new_str, line); + } } if (strcmp((*str)->data, new_str->data) != 0) Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump (original) +++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump Tue Feb 3 22:51:18 2015 @@ -64,10 +64,10 @@ PROPS-END Node-path: foo.txt Node-kind: file Node-action: add -Prop-content-length: 86 -Text-content-length: 0 Text-content-md5: d41d8cd98f00b204e9800998ecf8427e Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709 +Prop-content-length: 86 +Text-content-length: 0 Content-length: 86 K 13 @@ -83,3 +83,54 @@ V 51 PROPS-END +Revision-number: 3 +Prop-content-length: 97 +Content-length: 97 + +K 10 +svn:author +V 2 +pm +K 8 +svn:date +V 27 +2015-02-03T18:38:47.017031Z +K 7 +svn:log +V 1 +m +PROPS-END + +Node-path: zag +Node-kind: dir +Node-action: add +Prop-content-length: 76 +Content-length: 76 + +K 13 +svn:mergeinfo +V 45 +/a:1,4 +/b:0,4 +/c:2-3 +/d:0-3 +/e:2,5-6 +/f:0,5-6 +PROPS-END + + +Node-path: zig +Node-kind: dir +Node-action: add +Prop-content-length: 55 +Content-length: 55 + +K 13 +svn:mergeinfo +V 20 +/a:1 +/b:2-3 +/c:4,7-8 +PROPS-END + + Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.expected.dump URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.expected.dump?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.expected.dump (original) +++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.expected.dump Tue Feb 3 22:51:18 2015 @@ -64,10 +64,10 @@ PROPS-END Node-path: foo.txt Node-kind: file Node-action: add -Prop-content-length: 75 -Text-content-length: 0 Text-content-md5: d41d8cd98f00b204e9800998ecf8427e Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709 +Prop-content-length: 75 +Text-content-length: 0 Content-length: 75 K 13 @@ -83,3 +83,54 @@ V 40 PROPS-END +Revision-number: 3 +Prop-content-length: 97 +Content-length: 97 + +K 10 +svn:author +V 2 +pm +K 8 +svn:date +V 27 +2015-02-03T18:38:47.017031Z +K 7 +svn:log +V 1 +m +PROPS-END + +Node-path: zag +Node-kind: dir +Node-action: add +Prop-content-length: 76 +Content-length: 76 + +K 13 +svn:mergeinfo +V 41 +/a:1,4 +/b:4 +/c:2-3 +/d:1-3 +/e:2,5-6 +/f:5-6 +PROPS-END + + +Node-path: zig +Node-kind: dir +Node-action: add +Prop-content-length: 55 +Content-length: 55 + +K 13 +svn:mergeinfo +V 20 +/a:1 +/b:2-3 +/c:4,7-8 +PROPS-END + + Modified: subversion/branches/pin-externals/subversion/tests/libsvn_client/mtcc-test.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_client/mtcc-test.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_client/mtcc-test.c (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_client/mtcc-test.c Tue Feb 3 22:51:18 2015 @@ -87,6 +87,8 @@ make_greek_tree(const char *repos_url, subpool = svn_pool_create(scratch_pool); SVN_ERR(svn_client_create_context2(&ctx, NULL, subpool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, subpool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool)); for (i = 0; svn_test__greek_tree_nodes[i].path; i++) @@ -121,16 +123,14 @@ test_mkdir(const svn_test_opts_t *opts, { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-mkdir", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-mkdir", + opts, pool, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_mkdir("branches", mtcc, pool)); @@ -151,18 +151,16 @@ test_mkgreek(const svn_test_opts_t *opts { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-mkgreek", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-mkgreek", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_copy("A", 1, "greek_A", mtcc, pool)); @@ -178,18 +176,16 @@ test_swap(const svn_test_opts_t *opts, { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-swap", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-swap", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_move("A/B", "B", mtcc, pool)); @@ -207,18 +203,16 @@ test_propset(const svn_test_opts_t *opts { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-propset", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-propset", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_propset("iota", "key", @@ -281,18 +275,15 @@ test_update_files(const svn_test_opts_t { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - - repos_abspath = svn_test_data_path("mtcc-update-files", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-update-files", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); /* Update iota with knowledge of the old data */ @@ -331,18 +322,16 @@ test_overwrite(const svn_test_opts_t *op { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-overwrite", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-overwrite", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_copy("A", 1, "AA", mtcc, pool)); @@ -365,18 +354,15 @@ test_anchoring(const svn_test_opts_t *op { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-anchoring", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-anchoring", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); /* Update a file as root operation */ SVN_ERR(svn_client__mtcc_create(&mtcc, @@ -454,20 +440,16 @@ test_replace_tree(const svn_test_opts_t { svn_client__mtcc_t *mtcc; svn_client_ctx_t *ctx; - const char *repos_abspath; const char *repos_url; - svn_repos_t* repos; - repos_abspath = svn_test_data_path("mtcc-replace_tree", pool); - SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&repos_url, repos_abspath, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_abspath, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-replace_tree", + opts, pool, pool)); SVN_ERR(make_greek_tree(repos_url, pool)); SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); - /* Update a file as root operation */ SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, pool, pool)); SVN_ERR(svn_client__mtcc_add_delete("A", mtcc, pool)); @@ -484,6 +466,158 @@ test_replace_tree(const svn_test_opts_t return SVN_NO_ERROR; } +/* Baton for handle_rev */ +struct handle_rev_baton +{ + svn_revnum_t last; + svn_boolean_t up; + svn_boolean_t first; +}; + +/* Helper for test_file_revs_both_ways */ +static svn_error_t * +handle_rev(void *baton, + const char *path, + svn_revnum_t rev, + apr_hash_t *rev_props, + svn_boolean_t result_of_merge, + svn_txdelta_window_handler_t *delta_handler, + void **delta_baton, + apr_array_header_t *prop_diffs, + apr_pool_t *pool) +{ + struct handle_rev_baton *hrb = baton; + svn_revnum_t expected_rev = hrb->up ? (hrb->last + 1) : (hrb->last - 1); + + SVN_TEST_ASSERT(rev == expected_rev); + SVN_TEST_ASSERT(apr_hash_count(rev_props) >= 3); + SVN_TEST_STRING_ASSERT(path, (rev < 5) ? "/iota" : "/mu"); + + if (!hrb->first && rev == (hrb->up ? 5 : 4)) + SVN_TEST_ASSERT(delta_handler == NULL); + else + SVN_TEST_ASSERT(delta_handler != NULL); + + if (delta_handler) + { + *delta_handler = svn_delta_noop_window_handler; + *delta_baton = NULL; + } + + hrb->last = rev; + hrb->first = FALSE; + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_file_revs_both_ways(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_client__mtcc_t *mtcc; + svn_client_ctx_t *ctx; + apr_pool_t *subpool = svn_pool_create(pool); + const char *repos_url; + svn_ra_session_t *ra; + struct handle_rev_baton hrb; + + SVN_ERR(svn_test__create_repos2(NULL, &repos_url, NULL, "mtcc-file-revs", + opts, pool, subpool)); + + SVN_ERR(svn_client_create_context2(&ctx, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&ctx->auth_baton, pool)); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 0, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_add_file("iota", + cstr_stream("revision-1", subpool), + NULL /* src_checksum */, + mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 1, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 1, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_update_file("iota", + cstr_stream("revision-2", subpool), + NULL /* src_checksum */, NULL, NULL, + mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 2, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 2, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_update_file("iota", + cstr_stream("revision-3", subpool), + NULL /* src_checksum */, NULL, NULL, + mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 3, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 3, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_update_file("iota", + cstr_stream("revision-4", subpool), + NULL /* src_checksum */, NULL, NULL, + mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 4, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 4, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_move("iota", "mu", mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 5, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 5, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_update_file("mu", + cstr_stream("revision-6", subpool), + NULL /* src_checksum */, NULL, NULL, + mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 6, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client__mtcc_create(&mtcc, repos_url, 6, ctx, subpool, subpool)); + SVN_ERR(svn_client__mtcc_add_delete("mu", mtcc, subpool)); + SVN_ERR(verify_mtcc_commit(mtcc, 7, subpool)); + svn_pool_clear(subpool); + + SVN_ERR(svn_client_open_ra_session2(&ra, repos_url, NULL, ctx, pool, subpool)); + + svn_pool_clear(subpool); + hrb.up = FALSE; + hrb.last = 5; + hrb.first = TRUE; + SVN_ERR(svn_ra_get_file_revs2(ra, "iota", 4, 1, FALSE, + handle_rev, &hrb, + subpool)); + SVN_TEST_ASSERT(hrb.last == 1); + + svn_pool_clear(subpool); + hrb.up = TRUE; + hrb.last = 0; + hrb.first = TRUE; + SVN_ERR(svn_ra_get_file_revs2(ra, "iota", 1, 4, FALSE, + handle_rev, &hrb, + subpool)); + SVN_TEST_ASSERT(hrb.last == 4); + + svn_pool_clear(subpool); + hrb.up = FALSE; + hrb.last = 7; + hrb.first = TRUE; + SVN_ERR(svn_ra_get_file_revs2(ra, "mu", 6, 1, FALSE, + handle_rev, &hrb, + subpool)); + SVN_TEST_ASSERT(hrb.last == 1); + + svn_pool_clear(subpool); + hrb.up = TRUE; + hrb.last = 0; + hrb.first = TRUE; + SVN_ERR(svn_ra_get_file_revs2(ra, "mu", 1, 6, FALSE, + handle_rev, &hrb, + subpool)); + SVN_TEST_ASSERT(hrb.last == 6); + + return SVN_NO_ERROR; +} + /* ========================================================================== */ @@ -508,6 +642,8 @@ static struct svn_test_descriptor_t test "test mtcc anchoring for root operations"), SVN_TEST_OPTS_PASS(test_replace_tree, "test mtcc replace tree"), + SVN_TEST_OPTS_PASS(test_file_revs_both_ways, + "test ra_get_file_revs2 both ways"), SVN_TEST_NULL }; Propchange: subversion/branches/pin-externals/subversion/tests/libsvn_fs_x/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Feb 3 22:51:18 2015 @@ -62,6 +62,7 @@ /subversion/branches/revprop-cache/subversion/tests/libsvn_fs_x:1298521-1326293 /subversion/branches/revprop-packing/subversion/tests/libsvn_fs_x:1143907,1143971,1143997,1144017,1144499,1144568,1146145 /subversion/branches/subtree-mergeinfo/subversion/tests/libsvn_fs_x:876734-878766 +/subversion/branches/svn-auth-x509/subversion/tests/libsvn_fs_x:1603509-1655900 /subversion/branches/svn-mergeinfo-enhancements/subversion/tests/libsvn_fs_x:870119-870195,870197-870288 /subversion/branches/svn-patch-improvements/subversion/tests/libsvn_fs_x:918519-934609 /subversion/branches/svn_mutex/subversion/tests/libsvn_fs_x:1141683-1182099 @@ -80,4 +81,4 @@ /subversion/branches/verify-at-commit/subversion/tests/libsvn_fs_x:1462039-1462408 /subversion/branches/verify-keep-going/subversion/tests/libsvn_fs_x:1439280-1492639,1546002-1546110 /subversion/branches/wc-collate-path/subversion/tests/libsvn_fs_x:1402685-1480384 -/subversion/trunk/subversion/tests/libsvn_fs_x:1414756-1509914 +/subversion/trunk/subversion/tests/libsvn_fs_x:1414756-1509914,1643755-1656940 Modified: subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_ra/ra-test.c Tue Feb 3 22:51:18 2015 @@ -49,29 +49,21 @@ static const char tunnel_repos_name[] = static svn_error_t * -make_and_open_local_repos(svn_ra_session_t **session, - const char *repos_name, - const svn_test_opts_t *opts, - apr_pool_t *pool) +make_and_open_repos(svn_ra_session_t **session, + const char *repos_name, + const svn_test_opts_t *opts, + apr_pool_t *pool) { - svn_repos_t *repos; const char *url; svn_ra_callbacks2_t *cbtable; SVN_ERR(svn_ra_create_callbacks(&cbtable, pool)); - SVN_ERR(svn_cmdline_create_auth_baton(&cbtable->auth_baton, - TRUE /* non_interactive */, - "jrandom", "rayjandom", - NULL, - TRUE /* no_auth_cache */, - FALSE /* trust_server_cert */, - NULL, NULL, NULL, pool)); + SVN_ERR(svn_test__init_auth_baton(&cbtable->auth_baton, pool)); - SVN_ERR(svn_test__create_repos(&repos, repos_name, opts, pool)); + SVN_ERR(svn_test__create_repos2(NULL, &url, NULL, repos_name, opts, + pool, pool)); SVN_ERR(svn_ra_initialize(pool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(&url, repos_name, pool)); - SVN_ERR(svn_ra_open4(session, NULL, url, NULL, cbtable, NULL, NULL, pool)); return SVN_NO_ERROR; @@ -272,9 +264,9 @@ location_segments_test(const svn_test_op b.segments = segments; b.pool = pool; - SVN_ERR(make_and_open_local_repos(&session, - "test-repo-locsegs", opts, - pool)); + SVN_ERR(make_and_open_repos(&session, + "test-repo-locsegs", opts, + pool)); /* ### This currently tests only a small subset of what's possible. */ SVN_ERR(commit_changes(session, pool)); @@ -439,8 +431,11 @@ expect_error(const char *path, svn_lock_t *lock; struct lock_result_t *result = svn_hash_gets(results, path); - SVN_TEST_ASSERT(result && !result->lock && result->err); + SVN_TEST_ASSERT(result && result->err); + SVN_TEST_ASSERT(!result->lock); + /* RA layers shouldn't report SVN_ERR_FS_NOT_FOUND */ SVN_ERR(svn_ra_get_lock(session, &lock, path, scratch_pool)); + SVN_TEST_ASSERT(!lock); return SVN_NO_ERROR; } @@ -488,8 +483,7 @@ lock_test(const svn_test_opts_t *opts, struct lock_baton_t baton; apr_hash_index_t *hi; - SVN_ERR(make_and_open_local_repos(&session, "test-repo-lock", opts, - pool)); + SVN_ERR(make_and_open_repos(&session, "test-repo-lock", opts, pool)); SVN_ERR(commit_tree(session, pool)); baton.results = apr_hash_make(pool); @@ -564,11 +558,31 @@ lock_test(const svn_test_opts_t *opts, return SVN_NO_ERROR; } +/* Test svn_ra_get_dir2(). */ +static svn_error_t * +get_dir_test(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_ra_session_t *session; + apr_hash_t *dirents; + + SVN_ERR(make_and_open_repos(&session, "test-get-dir", opts, pool)); + SVN_ERR(commit_tree(session, pool)); + + /* This call used to block on ra-svn for 1.8.0...r1656713 */ + SVN_TEST_ASSERT_ERROR(svn_ra_get_dir2(session, &dirents, NULL, NULL, + "non/existing/relpath", 1, + SVN_DIRENT_KIND, pool), + SVN_ERR_FS_NOT_FOUND); + + return SVN_NO_ERROR; +} + /* The test table. */ -static int max_threads = 1; +static int max_threads = 2; static struct svn_test_descriptor_t test_funcs[] = { @@ -581,6 +595,8 @@ static struct svn_test_descriptor_t test "test ra_svn tunnel creation callbacks"), SVN_TEST_OPTS_PASS(lock_test, "lock multiple paths"), + SVN_TEST_OPTS_PASS(get_dir_test, + "test ra_get_dir2"), SVN_TEST_NULL }; Modified: subversion/branches/pin-externals/subversion/tests/libsvn_subr/utf-test.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_subr/utf-test.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_subr/utf-test.c (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_subr/utf-test.c Tue Feb 3 22:51:18 2015 @@ -737,6 +737,92 @@ test_utf_is_normalized(apr_pool_t *pool) return SVN_NO_ERROR; } + +static svn_error_t * +test_utf_conversions(apr_pool_t *pool) +{ + static const struct cvt_test_t + { + svn_boolean_t sixteenbit; + svn_boolean_t bigendian; + const char *source; + const char *result; + } tests[] = { + +#define UTF_32_LE FALSE, FALSE +#define UTF_32_BE FALSE, TRUE +#define UTF_16_LE TRUE, FALSE +#define UTF_16_BE TRUE, TRUE + + /* Normal character conversion */ + { UTF_32_LE, "t\0\0\0" "e\0\0\0" "s\0\0\0" "t\0\0\0" "\0\0\0\0", "test" }, + { UTF_32_BE, "\0\0\0t" "\0\0\0e" "\0\0\0s" "\0\0\0t" "\0\0\0\0", "test" }, + { UTF_16_LE, "t\0" "e\0" "s\0" "t\0" "\0\0", "test" }, + { UTF_16_BE, "\0t" "\0e" "\0s" "\0t" "\0\0", "test" }, + + /* Valid surrogate pairs */ + { UTF_16_LE, "\x00\xD8" "\x00\xDC" "\0\0", "\xf0\x90\x80\x80" }, /* U+010000 */ + { UTF_16_LE, "\x34\xD8" "\x1E\xDD" "\0\0", "\xf0\x9d\x84\x9e" }, /* U+01D11E */ + { UTF_16_LE, "\xFF\xDB" "\xFD\xDF" "\0\0", "\xf4\x8f\xbf\xbd" }, /* U+10FFFD */ + + { UTF_16_BE, "\xD8\x00" "\xDC\x00" "\0\0", "\xf0\x90\x80\x80" }, /* U+010000 */ + { UTF_16_BE, "\xD8\x34" "\xDD\x1E" "\0\0", "\xf0\x9d\x84\x9e" }, /* U+01D11E */ + { UTF_16_BE, "\xDB\xFF" "\xDF\xFD" "\0\0", "\xf4\x8f\xbf\xbd" }, /* U+10FFFD */ + + /* Swapped, single and trailing surrogate pairs */ + { UTF_16_LE, "*\0" "\x00\xDC" "\x00\xD8" "*\0\0\0", "*\xed\xb0\x80" "\xed\xa0\x80*" }, + { UTF_16_LE, "*\0" "\x1E\xDD" "*\0\0\0", "*\xed\xb4\x9e*" }, + { UTF_16_LE, "*\0" "\xFF\xDB" "*\0\0\0", "*\xed\xaf\xbf*" }, + { UTF_16_LE, "\x1E\xDD" "\0\0", "\xed\xb4\x9e" }, + { UTF_16_LE, "\xFF\xDB" "\0\0", "\xed\xaf\xbf" }, + + { UTF_16_BE, "\0*" "\xDC\x00" "\xD8\x00" "\0*\0\0", "*\xed\xb0\x80" "\xed\xa0\x80*" }, + { UTF_16_BE, "\0*" "\xDD\x1E" "\0*\0\0", "*\xed\xb4\x9e*" }, + { UTF_16_BE, "\0*" "\xDB\xFF" "\0*\0\0", "*\xed\xaf\xbf*" }, + { UTF_16_BE, "\xDD\x1E" "\0\0", "\xed\xb4\x9e" }, + { UTF_16_BE, "\xDB\xFF" "\0\0", "\xed\xaf\xbf" }, + +#undef UTF_32_LE +#undef UTF_32_BE +#undef UTF_16_LE +#undef UTF_16_BE + + { 0 } + }; + + const struct cvt_test_t *tc; + const svn_string_t *result; + int i; + + for (i = 1, tc = tests; tc->source; ++tc, ++i) + { + if (tc->sixteenbit) + SVN_ERR(svn_utf__utf16_to_utf8(&result, (const void*)tc->source, + SVN_UTF__UNKNOWN_LENGTH, + tc->bigendian, pool, pool)); + else + SVN_ERR(svn_utf__utf32_to_utf8(&result, (const void*)tc->source, + SVN_UTF__UNKNOWN_LENGTH, + tc->bigendian, pool, pool)); + SVN_ERR_ASSERT(0 == strcmp(result->data, tc->result)); + } + + /* Test counted strings with NUL characters */ + SVN_ERR(svn_utf__utf16_to_utf8( + &result, (void*)("x\0" "\0\0" "y\0" "*\0"), 3, + FALSE, pool, pool)); + SVN_ERR_ASSERT(0 == memcmp(result->data, "x\0y", 3)); + + SVN_ERR(svn_utf__utf32_to_utf8( + &result, + (void*)("\0\0\0x" "\0\0\0\0" "\0\0\0y" "\0\0\0*"), 3, + TRUE, pool, pool)); + SVN_ERR_ASSERT(0 == memcmp(result->data, "x\0y", 3)); + + return SVN_NO_ERROR; +} + + /* The test table. */ @@ -761,6 +847,8 @@ static struct svn_test_descriptor_t test "test svn_utf__fuzzy_escape"), SVN_TEST_PASS2(test_utf_is_normalized, "test svn_utf__is_normalized"), + SVN_TEST_PASS2(test_utf_conversions, + "test svn_utf__utf{16,32}_to_utf8"), SVN_TEST_NULL }; Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/op-depth-test.c Tue Feb 3 22:51:18 2015 @@ -718,7 +718,7 @@ repo_wc_copies(svn_test__sandbox_t *b) } /* Perform each copy. */ - SVN_ERR(svn_client_create_context(&ctx, b->pool)); + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); for (subtest = subtests; subtest->from_path; subtest++) { svn_opt_revision_t rev = { svn_opt_revision_number, { 1 } }; @@ -9690,7 +9690,6 @@ static svn_error_t * repo_wc_copy(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_test__sandbox_t b; - const char *repos_dir; const char *new_repos_dir; const char *new_repos_url; @@ -9718,15 +9717,13 @@ repo_wc_copy(const svn_test_opts_t *opts SVN_ERR(check_db_rows(&b, "AA", nodes)); } - SVN_ERR(svn_uri_get_dirent_from_file_url(&repos_dir, b.repos_url, - pool)); - new_repos_dir = apr_pstrcat(pool, repos_dir, "-2", SVN_VA_NULL); + new_repos_dir = apr_pstrcat(pool, b.repos_dir, "-2", SVN_VA_NULL); new_repos_url = apr_pstrcat(pool, b.repos_url, "-2", SVN_VA_NULL); svn_test_add_dir_cleanup(new_repos_dir); SVN_ERR(svn_io_remove_dir2(new_repos_dir, TRUE, NULL, NULL, pool)); - SVN_ERR(svn_io_copy_dir_recursively(repos_dir, + SVN_ERR(svn_io_copy_dir_recursively(b.repos_dir, svn_dirent_dirname(new_repos_dir, pool), svn_dirent_basename(new_repos_dir, pool), FALSE, NULL, NULL, pool)); Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.c (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.c Tue Feb 3 22:51:18 2015 @@ -22,6 +22,7 @@ #include "svn_error.h" #include "svn_client.h" +#include "svn_cmdline.h" #include "svn_pools.h" #include "utils.h" @@ -33,9 +34,25 @@ #define SVN_WC__I_AM_WC_DB #include "../../libsvn_wc/wc_db_private.h" +svn_error_t * +svn_test__create_client_ctx(svn_client_ctx_t **ctx, + svn_test__sandbox_t *sbox, + apr_pool_t *result_pool) +{ + SVN_ERR(svn_client_create_context2(ctx, NULL, result_pool)); + + SVN_ERR(svn_test__init_auth_baton(&(*ctx)->auth_baton, + result_pool)); + + if (sbox) + (*ctx)->wc_ctx = sbox->wc_ctx; + + return SVN_NO_ERROR; +} /* Create an empty repository and WC for the test TEST_NAME. Set *REPOS_URL - * to the URL of the new repository and *WC_ABSPATH to the root path of the + * to the URL of the new repository, *REPOS_DIR to its local path and + * *WC_ABSPATH to the root path of the * new WC. * * Create the repository and WC in subdirectories called @@ -45,6 +62,7 @@ * Register the repo and WC to be cleaned up when the test suite exits. */ static svn_error_t * create_repos_and_wc(const char **repos_url, + const char **repos_dir, const char **wc_abspath, const char *test_name, const svn_test_opts_t *opts, @@ -65,8 +83,6 @@ create_repos_and_wc(const char **repos_u /* Create a repos. Register it for clean-up. Set *REPOS_URL to its path. */ { - svn_repos_t *repos; - /* Use a subpool to create the repository and then destroy the subpool so the repository's underlying filesystem is closed. If opts->fs_type is BDB this prevents any attempt to open a second environment handle @@ -74,8 +90,8 @@ create_repos_and_wc(const char **repos_u only a single environment handle to be open per process. */ apr_pool_t *subpool = svn_pool_create(pool); - SVN_ERR(svn_test__create_repos(&repos, repos_path, opts, subpool)); - SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_path, pool)); + SVN_ERR(svn_test__create_repos2(NULL, repos_url, repos_dir, repos_path, + opts, pool, subpool)); svn_pool_destroy(subpool); } @@ -85,7 +101,7 @@ create_repos_and_wc(const char **repos_u svn_client_ctx_t *ctx; svn_opt_revision_t head_rev = { svn_opt_revision_head, {0} }; - SVN_ERR(svn_client_create_context2(&ctx, NULL, subpool)); + SVN_ERR(svn_test__create_client_ctx(&ctx, NULL, subpool)); SVN_ERR(svn_dirent_get_absolute(wc_abspath, wc_path, pool)); SVN_ERR(svn_client_checkout3(NULL, *repos_url, *wc_abspath, &head_rev, &head_rev, svn_depth_infinity, @@ -101,7 +117,6 @@ create_repos_and_wc(const char **repos_u return SVN_NO_ERROR; } - WC_QUERIES_SQL_DECLARE_STATEMENTS(statements); svn_error_t * @@ -149,7 +164,8 @@ svn_test__sandbox_create(svn_test__sandb apr_pool_t *pool) { sandbox->pool = pool; - SVN_ERR(create_repos_and_wc(&sandbox->repos_url, &sandbox->wc_abspath, + SVN_ERR(create_repos_and_wc(&sandbox->repos_url, &sandbox->repos_dir, + &sandbox->wc_abspath, test_name, opts, pool)); SVN_ERR(svn_wc_context_create(&sandbox->wc_ctx, NULL, pool, pool)); return SVN_NO_ERROR; @@ -240,8 +256,7 @@ sbox_wc_copy_url(svn_test__sandbox_t *b, scratch_pool, 1, sizeof(svn_client_copy_source_t *)); - SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool)); if (SVN_IS_VALID_REVNUM(revision)) { @@ -334,8 +349,7 @@ sbox_wc_commit_ex(svn_test__sandbox_t *b apr_pool_t *scratch_pool = svn_pool_create(b->pool); svn_error_t *err; - SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool)); /* A successfull commit doesn't close the ra session, but leaves that to the caller. This leaves the BDB handle open, which might cause @@ -387,8 +401,8 @@ sbox_wc_update_depth(svn_test__sandbox_t } APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path); - SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + return svn_client_update4(&result_revs, paths, &revision, depth, sticky, FALSE, FALSE, FALSE, FALSE, ctx, b->pool); @@ -412,8 +426,8 @@ sbox_wc_switch(svn_test__sandbox_t *b, svn_opt_revision_t head_rev = { svn_opt_revision_head, {0} }; url = apr_pstrcat(b->pool, b->repos_url, url, SVN_VA_NULL); - SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + return svn_client_switch3(&result_rev, sbox_wc_path(b, path), url, &head_rev, &head_rev, depth, FALSE /* depth_is_sticky */, @@ -464,8 +478,8 @@ sbox_wc_move(svn_test__sandbox_t *b, con apr_array_header_t *paths = apr_array_make(b->pool, 1, sizeof(const char *)); - SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, src); return svn_client_move7(paths, sbox_wc_path(b, dst), FALSE /* move_as_child */, @@ -488,8 +502,8 @@ sbox_wc_propset(svn_test__sandbox_t *b, sizeof(const char *)); svn_string_t *pval = value ? svn_string_create(value, b->pool) : NULL; - SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, b->pool)); + APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path); return svn_client_propset_local(name, pval, paths, svn_depth_empty, TRUE /* skip_checks */, @@ -503,8 +517,7 @@ sbox_wc_relocate(svn_test__sandbox_t *b, apr_pool_t *scratch_pool = b->pool; svn_client_ctx_t *ctx; - SVN_ERR(svn_client_create_context2(&ctx, NULL, scratch_pool)); - ctx->wc_ctx = b->wc_ctx; + SVN_ERR(svn_test__create_client_ctx(&ctx, b, scratch_pool)); SVN_ERR(svn_client_relocate2(b->wc_abspath, b->repos_url, new_repos_url, FALSE, ctx,scratch_pool)); Modified: subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.h URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.h?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.h (original) +++ subversion/branches/pin-externals/subversion/tests/libsvn_wc/utils.h Tue Feb 3 22:51:18 2015 @@ -25,6 +25,8 @@ #include <apr_pools.h> #include "svn_error.h" +#include "svn_client.h" + #include "../svn_test.h" #ifdef __cplusplus @@ -53,6 +55,8 @@ typedef struct svn_test__sandbox_t svn_wc_context_t *wc_ctx; /* The repository URL. */ const char *repos_url; + /* Local path to the repository */ + const char *repos_dir; /* The absolute local path of the WC root. */ const char *wc_abspath; /* A pool that can be used for all allocations. */ @@ -185,6 +189,13 @@ svn_test__create_fake_wc(const char *wc_ apr_pool_t *scratch_pool); +/* Create a client context for the specified sandbox */ +svn_error_t * +svn_test__create_client_ctx(svn_client_ctx_t **ctx, + svn_test__sandbox_t *sbox, + apr_pool_t *result_pool); + + #ifdef __cplusplus } #endif /* __cplusplus */ Modified: subversion/branches/pin-externals/subversion/tests/svn_test.h URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test.h?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/svn_test.h (original) +++ subversion/branches/pin-externals/subversion/tests/svn_test.h Tue Feb 3 22:51:18 2015 @@ -34,6 +34,7 @@ #include "svn_types.h" #include "svn_error.h" #include "svn_string.h" +#include "svn_auth.h" #ifdef __cplusplus extern "C" { @@ -117,12 +118,20 @@ extern "C" { */ typedef struct svn_test_opts_t { + /* The name of the application (to generate unique names) */ + const char *prog_name; /* Description of the fs backend that should be used for testing. */ const char *fs_type; /* Config file. */ const char *config_file; /* Source dir. */ const char *srcdir; + /* Repository dir: temporary directory to create repositories in as subdir */ + const char *repos_dir; + /* Repository url: The url to access REPOS_DIR as */ + const char *repos_url; + /* Repository template: pre-created repository to copy for tests */ + const char *repos_template; /* Minor version to use for servers and FS backends, or zero to use the current latest version. */ int server_minor_version; @@ -269,6 +278,11 @@ svn_test_get_srcdir(const char **srcdir, const svn_test_opts_t *opts, apr_pool_t *pool); +/* Initializes a standard auth baton for accessing the repositories */ +svn_error_t * +svn_test__init_auth_baton(svn_auth_baton_t **baton, + apr_pool_t *result_pool); + #ifdef __cplusplus } #endif /* __cplusplus */ Modified: subversion/branches/pin-externals/subversion/tests/svn_test_fs.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test_fs.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/svn_test_fs.c (original) +++ subversion/branches/pin-externals/subversion/tests/svn_test_fs.c Tue Feb 3 22:51:18 2015 @@ -212,42 +212,115 @@ svn_test__create_fs(svn_fs_t **fs_p, } svn_error_t * -svn_test__create_repos(svn_repos_t **repos_p, - const char *name, - const svn_test_opts_t *opts, - apr_pool_t *pool) +svn_test__create_repos2(svn_repos_t **repos_p, + const char **repos_url, + const char **repos_dirent, + const char *name, + const svn_test_opts_t *opts, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { svn_repos_t *repos; svn_boolean_t must_reopen; + const char *repos_abspath; + apr_pool_t *repos_pool = repos_p ? result_pool : scratch_pool; + svn_boolean_t init_svnserve = FALSE; apr_hash_t *fs_config = make_fs_config(opts->fs_type, - opts->server_minor_version, pool); + opts->server_minor_version, + repos_pool); + + if (repos_url && opts->repos_dir && opts->repos_url) + { + name = apr_psprintf(scratch_pool, "%s-%s", opts->prog_name, + svn_dirent_basename(name, NULL)); + + repos_abspath = svn_dirent_join(opts->repos_dir, name, scratch_pool); + + SVN_ERR(svn_dirent_get_absolute(&repos_abspath, repos_abspath, + scratch_pool)); + + SVN_ERR(svn_io_make_dir_recursively(repos_abspath, scratch_pool)); + + *repos_url = svn_path_url_add_component2(opts->repos_url, name, + result_pool); + + if (strstr(opts->repos_url, "svn://")) + init_svnserve = TRUE; + } + else + { + SVN_ERR(svn_dirent_get_absolute(&repos_abspath, name, scratch_pool)); + + if (repos_url) + SVN_ERR(svn_uri_get_file_url_from_dirent(repos_url, repos_abspath, + result_pool)); + } /* If there's already a repository named NAME, delete it. Doing things this way means that repositories stick around after a failure for postmortem analysis, but also that tests can be re-run without cleaning out the repositories created by prior runs. */ - SVN_ERR(svn_io_remove_dir2(name, TRUE, NULL, NULL, pool)); + SVN_ERR(svn_io_remove_dir2(repos_abspath, TRUE, NULL, NULL, scratch_pool)); - SVN_ERR(svn_repos_create(&repos, name, NULL, NULL, NULL, - fs_config, pool)); + SVN_ERR(svn_repos_create(&repos, repos_abspath, NULL, NULL, NULL, + fs_config, repos_pool)); /* Register this repo for cleanup. */ - svn_test_add_dir_cleanup(name); + svn_test_add_dir_cleanup(repos_abspath); SVN_ERR(maybe_install_fs_conf(svn_repos_fs(repos), opts, &must_reopen, - pool)); + scratch_pool)); if (must_reopen) { - SVN_ERR(svn_repos_open3(&repos, name, NULL, pool, pool)); - svn_fs_set_warning_func(svn_repos_fs(repos), fs_warning_handler, NULL); + SVN_ERR(svn_repos_open3(&repos, repos_abspath, NULL, repos_pool, + scratch_pool)); } - *repos_p = repos; + svn_fs_set_warning_func(svn_repos_fs(repos), fs_warning_handler, NULL); + + if (init_svnserve) + { + const char *cfg; + const char *pwd; + + cfg = svn_dirent_join(repos_abspath, "conf/svnserve.conf", scratch_pool); + SVN_ERR(svn_io_remove_file2(cfg, FALSE, scratch_pool)); + SVN_ERR(svn_io_file_create(cfg, + "[general]\n" + "auth-access = write\n" + "password-db = passwd\n", + scratch_pool)); + + pwd = svn_dirent_join(repos_abspath, "conf/passwd", scratch_pool); + SVN_ERR(svn_io_remove_file2(pwd, FALSE, scratch_pool)); + SVN_ERR(svn_io_file_create(pwd, + "[users]\n" + "jrandom = rayjandom\n" + "jconstant = rayjandom\n", + scratch_pool)); + } + + if (repos_p) + *repos_p = repos; + if (repos_dirent) + *repos_dirent = apr_pstrdup(result_pool, repos_abspath); + return SVN_NO_ERROR; } svn_error_t * +svn_test__create_repos(svn_repos_t **repos_p, + const char *name, + const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + return svn_error_trace( + svn_test__create_repos2(repos_p, NULL, NULL, name, + opts, pool, pool)); +} + +svn_error_t * svn_test__stream_to_string(svn_stringbuf_t **string, svn_stream_t *stream, apr_pool_t *pool) Modified: subversion/branches/pin-externals/subversion/tests/svn_test_fs.h URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test_fs.h?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/svn_test_fs.h (original) +++ subversion/branches/pin-externals/subversion/tests/svn_test_fs.h Tue Feb 3 22:51:18 2015 @@ -82,6 +82,19 @@ svn_test__create_repos(svn_repos_t **rep const svn_test_opts_t *opts, apr_pool_t *pool); +/* Create a repository with a filesystem based on OPTS in a subdir NAME + and return optionally new REPOS object, the directory it was created in + and/or the url of the repository . */ +svn_error_t * +svn_test__create_repos2(svn_repos_t **repos_p, + const char **repos_url, + const char **repos_dirent, + const char *name, + const svn_test_opts_t *opts, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + + /* Read all data from a generic read STREAM, and return it in STRING. Allocate the svn_stringbuf_t in POOL. (All data in STRING will be dup'ed from STREAM using POOL too.) */ Modified: subversion/branches/pin-externals/subversion/tests/svn_test_main.c URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/svn_test_main.c?rev=1656942&r1=1656941&r2=1656942&view=diff ============================================================================== --- subversion/branches/pin-externals/subversion/tests/svn_test_main.c (original) +++ subversion/branches/pin-externals/subversion/tests/svn_test_main.c Tue Feb 3 22:51:18 2015 @@ -101,6 +101,9 @@ enum test_options_e { server_minor_version_opt, allow_segfault_opt, srcdir_opt, + reposdir_opt, + reposurl_opt, + repostemplate_opt, mode_filter_opt, sqlite_log_opt, parallel_opt, @@ -135,6 +138,12 @@ static const apr_getopt_option_t cl_opti N_("don't trap seg faults (useful for debugging)")}, {"srcdir", srcdir_opt, 1, N_("directory which contains test's C source files")}, + {"repos-dir", reposdir_opt, 1, + N_("directory to create repositories in")}, + {"repos-url", reposurl_opt, 1, + N_("the url to access reposdir as")}, + {"repos-template",repostemplate_opt, 1, + N_("the repository to use as template")}, {"sqlite-logging", sqlite_log_opt, 0, N_("enable SQLite logging")}, {"parallel", parallel_opt, 0, @@ -682,12 +691,26 @@ svn_test_get_srcdir(const char **srcdir, return SVN_NO_ERROR; } +svn_error_t * +svn_test__init_auth_baton(svn_auth_baton_t **ab, + apr_pool_t *result_pool) +{ + SVN_ERR(svn_cmdline_create_auth_baton(ab, + TRUE /* non_interactive */, + "jrandom", "rayjandom", + NULL, + TRUE /* no_auth_cache */, + FALSE /* trust_server_cert */, + NULL, NULL, NULL, result_pool)); + + return SVN_NO_ERROR; +} + /* Standard svn test program */ int svn_test_main(int argc, const char *argv[], int max_threads, struct svn_test_descriptor_t *test_funcs) { - const char *prog_name; int i; svn_boolean_t got_error = FALSE; apr_pool_t *pool, *test_pool; @@ -745,21 +768,19 @@ svn_test_main(int argc, const char *argv os->interleave = TRUE; /* Let options and arguments be interleaved */ /* Strip off any leading path components from the program name. */ - prog_name = strrchr(argv[0], '/'); - if (prog_name) - prog_name++; - else - { - /* Just check if this is that weird platform that uses \ instead - of / for the path separator. */ - prog_name = strrchr(argv[0], '\\'); - if (prog_name) - prog_name++; - else - prog_name = argv[0]; - } + opts.prog_name = svn_dirent_internal_style(argv[0], pool); + opts.prog_name = svn_dirent_basename(opts.prog_name, NULL); #ifdef WIN32 + /* Abuse cast in strstr() to remove .exe extension. + Value is allocated in pool by svn_dirent_internal_style() */ + { + char *exe_ext = strstr(opts.prog_name, ".exe"); + + if (exe_ext) + *exe_ext = '\0'; + } + #if _MSC_VER >= 1400 /* ### This should work for VC++ 2002 (=1300) and later */ /* Show the abort message on STDERR instead of a dialog to allow @@ -781,7 +802,7 @@ svn_test_main(int argc, const char *argv #endif if (err) - return svn_cmdline_handle_exit_error(err, pool, prog_name); + return svn_cmdline_handle_exit_error(err, pool, opts.prog_name); while (1) { const char *opt_arg; @@ -800,7 +821,7 @@ svn_test_main(int argc, const char *argv switch (opt_id) { case help_opt: - help(prog_name, pool); + help(opts.prog_name, pool); exit(0); case cleanup_opt: cleanup_mode = TRUE; @@ -815,6 +836,20 @@ svn_test_main(int argc, const char *argv SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.srcdir, opt_arg, pool)); opts.srcdir = svn_dirent_internal_style(opts.srcdir, pool); break; + case reposdir_opt: + SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.repos_dir, opt_arg, pool)); + opts.repos_dir = svn_dirent_internal_style(opts.repos_dir, pool); + break; + case reposurl_opt: + SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.repos_url, opt_arg, pool)); + opts.repos_url = svn_uri_canonicalize(opts.repos_url, pool); + break; + case repostemplate_opt: + SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.repos_template, opt_arg, + pool)); + opts.repos_template = svn_dirent_internal_style(opts.repos_template, + pool); + break; case list_opt: list_mode = TRUE; break; @@ -903,7 +938,7 @@ svn_test_main(int argc, const char *argv "------ ----- ----------------\n"; for (i = 1; i <= array_size; i++) { - if (do_test_num(prog_name, i, test_funcs, + if (do_test_num(opts.prog_name, i, test_funcs, TRUE, &opts, &header_msg, test_pool)) got_error = TRUE; @@ -924,7 +959,7 @@ svn_test_main(int argc, const char *argv continue; ran_a_test = TRUE; - if (do_test_num(prog_name, test_num, test_funcs, + if (do_test_num(opts.prog_name, test_num, test_funcs, FALSE, &opts, NULL, test_pool)) got_error = TRUE; @@ -946,7 +981,7 @@ svn_test_main(int argc, const char *argv { for (i = 1; i <= array_size; i++) { - if (do_test_num(prog_name, i, test_funcs, + if (do_test_num(opts.prog_name, i, test_funcs, FALSE, &opts, NULL, test_pool)) got_error = TRUE; @@ -958,7 +993,7 @@ svn_test_main(int argc, const char *argv #if APR_HAS_THREADS else { - got_error = do_tests_concurrently(prog_name, test_funcs, + got_error = do_tests_concurrently(opts.prog_name, test_funcs, array_size, max_threads, &opts, test_pool);
