You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/05/26 10:57:34 UTC
svn commit: r1681721 [2/3] - in /subversion/branches/move-tracking-2: ./
subversion/ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/
subversion/libsvn_subr/ subversion/libsvn_wc...
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cache-membuffer.c Tue May 26 08:57:33 2015
@@ -28,13 +28,16 @@
#include "svn_pools.h"
#include "svn_checksum.h"
#include "svn_private_config.h"
-#include "cache.h"
#include "svn_string.h"
#include "svn_sorts.h" /* get the MIN macro */
+
#include "private/svn_atomic.h"
#include "private/svn_dep_compat.h"
#include "private/svn_mutex.h"
-#include "private/svn_pseudo_md5.h"
+#include "private/svn_string_private.h"
+
+#include "cache.h"
+#include "fnv1a.h"
/*
* This svn_cache__t implementation actually consists of two parts:
@@ -45,8 +48,9 @@
* A membuffer cache consists of two parts:
*
* 1. A linear data buffer containing cached items in a serialized
- * representation. There may be arbitrary gaps between entries.
- * This buffer is sub-devided into (currently two) cache levels.
+ * representation, prefixed by their full cache keys. There may be
+ * arbitrary gaps between entries. This buffer is sub-devided into
+ * (currently two) cache levels.
*
* 2. A directory of cache entries. This is organized similar to CPU
* data caches: for every possible key, there is exactly one group
@@ -78,9 +82,10 @@
* Insertion can occur at only one, sliding position per cache level. It is
* marked by its offset in the data buffer and the index of the first used
* entry at or behind that position. If this gap is too small to accommodate
- * the new item, the insertion window is extended as described below. The new
- * entry will always be inserted at the bottom end of the window and since
- * the next used entry is known, properly sorted insertion is possible.
+ * the new item (plus its full key), the insertion window is extended as
+ * described below. The new entry will always be inserted at the bottom end
+ * of the window and since the next used entry is known, properly sorted
+ * insertion is possible.
*
* To make the cache perform robustly in a wide range of usage scenarios,
* L2 uses a randomized variant of LFU (see ensure_data_insertable_l2 for
@@ -104,11 +109,13 @@
* an already used group to extend it.
*
* To limit the entry size and management overhead, not the actual item keys
- * but only their MD5-based hashes will be stored. This is reasonably safe
- * to do since users have only limited control over the full keys, even if
- * these contain folder paths. So, it is very hard to deliberately construct
- * colliding keys. Random checksum collisions can be shown to be extremely
- * unlikely.
+ * but only their hashed "fingerprint" will be stored. These are reasonably
+ * unique to prevent collisions, so we only need to support up to one entry
+ * per entry key. To guarantee that there are no conflicts, however, we
+ * store the actual full key immediately in front of the serialized item
+ * data. That is, the entry offset actually points to the full key and the
+ * key length stored in the entry acts as an additional offset to find the
+ * actual item.
*
* All access to the cached data needs to be serialized. Because we want
* to scale well despite that bottleneck, we simply segment the cache into
@@ -178,17 +185,34 @@
*/
#define MAX_ITEM_SIZE ((apr_uint32_t)(0 - ITEM_ALIGNMENT))
-/* A 16 byte key type. We use that to identify cache entries.
- * The notation as just two integer values will cause many compilers
- * to create better code.
+/* We use this structure to identify cache entries. There cannot be two
+ * entries with the same entry key. However unlikely, though, two different
+ * full keys (see full_key_t) may have the same entry key. That is a
+ * collision and at most one of them can be stored in the cache at any time.
*/
-typedef apr_uint64_t entry_key_t[2];
+typedef struct entry_key_t
+{
+ /* 16 byte finger print of the full key. */
+ apr_uint64_t fingerprint[2];
-/* The prefix passed to svn_cache__create_membuffer_cache() effectively
- * defines the type of all items stored by that cache instance. We'll take
- * the last 15 bytes + \0 as plaintext for easy identification by the dev.
+ /* Length of the full key. This value is aligned to ITEM_ALIGNMENT to
+ * make sure the subsequent item content is properly aligned. */
+ apr_size_t key_len;
+} entry_key_t;
+
+/* A full key, i.e. the combination of the cache's key prefix with some
+ * dynamic part appended to it. It also contains its ENTRY_KEY.
*/
-#define PREFIX_TAIL_LEN 16
+typedef struct full_key_t
+{
+ /* Reduced form identifying the cache entry (if such an entry exists). */
+ entry_key_t entry_key;
+
+ /* This contains the full combination. Note that the SIZE element may
+ * be larger than ENTRY_KEY.KEY_LEN, but only the latter determines the
+ * valid key size. */
+ svn_membuf_t full_key;
+} full_key_t;
/* Debugging / corruption detection support.
* If you define this macro, the getter functions will performed expensive
@@ -198,6 +222,12 @@ typedef apr_uint64_t entry_key_t[2];
*/
#ifdef SVN_DEBUG_CACHE_MEMBUFFER
+/* The prefix passed to svn_cache__create_membuffer_cache() effectively
+ * defines the type of all items stored by that cache instance. We'll take
+ * the last 15 bytes + \0 as plaintext for easy identification by the dev.
+ */
+#define PREFIX_TAIL_LEN 16
+
/* This record will be attached to any cache entry. It tracks item data
* (content), key and type as hash values and is the baseline against which
* the getters will compare their results to detect inconsistencies.
@@ -233,22 +263,33 @@ typedef struct entry_tag_t
/* Initialize all members of TAG except for the content hash.
*/
static svn_error_t *store_key_part(entry_tag_t *tag,
- entry_key_t prefix_hash,
- char *prefix_tail,
+ const full_key_t *prefix_key,
const void *key,
apr_size_t key_len,
apr_pool_t *pool)
{
svn_checksum_t *checksum;
+ const char *prefix = prefix_key->full_key.data;
+ apr_size_t prefix_len = strlen(prefix);
+
+ if (prefix_len > sizeof(tag->prefix_tail))
+ {
+ prefix += prefix_len - (sizeof(tag->prefix_tail) - 1);
+ prefix_len = sizeof(tag->prefix_tail) - 1;
+ }
+
SVN_ERR(svn_checksum(&checksum,
svn_checksum_md5,
key,
key_len,
pool));
- memcpy(tag->prefix_hash, prefix_hash, sizeof(tag->prefix_hash));
+ memcpy(tag->prefix_hash, prefix_key->entry_key.fingerprint,
+ sizeof(tag->prefix_hash));
memcpy(tag->key_hash, checksum->digest, sizeof(tag->key_hash));
- memcpy(tag->prefix_tail, prefix_tail, sizeof(tag->prefix_tail));
+
+ memset(tag->prefix_tail, 0, sizeof(tag->key_hash));
+ memcpy(tag->prefix_tail, prefix, prefix_len + 1);
tag->key_len = key_len;
@@ -258,7 +299,7 @@ static svn_error_t *store_key_part(entry
/* Initialize the content hash member of TAG.
*/
static svn_error_t* store_content_part(entry_tag_t *tag,
- const char *data,
+ const void *data,
apr_size_t size,
apr_pool_t *pool)
{
@@ -305,8 +346,7 @@ static svn_error_t* assert_equal_tags(co
entry_tag_t *tag = &_tag; \
if (key) \
SVN_ERR(store_key_part(tag, \
- cache->prefix, \
- cache->info_prefix, \
+ &cache->prefix, \
key, \
cache->key_len == APR_HASH_KEY_STRING \
? strlen((const char *) key) \
@@ -323,23 +363,6 @@ static svn_error_t* assert_equal_tags(co
#endif /* SVN_DEBUG_CACHE_MEMBUFFER */
-/* Per svn_cache_t instance initialization helper.
- * Copy the last to up PREFIX_TAIL_LEN-1 chars from PREFIX to PREFIX_TAIL.
- * If the prefix has been structured by ':', only store the last element
- * (which will tell us the type).
- */
-static void get_prefix_tail(const char *prefix, char *prefix_tail)
-{
- apr_size_t len = strlen(prefix);
- apr_size_t to_copy = MIN(len, PREFIX_TAIL_LEN - 1);
- const char *last_colon = strrchr(prefix, ':');
- apr_size_t last_element_pos = last_colon ? 0 : last_colon - prefix + 1;
-
- to_copy = MIN(to_copy, len - last_element_pos);
- memset(prefix_tail, 0, PREFIX_TAIL_LEN);
- memcpy(prefix_tail, prefix + len - to_copy, to_copy);
-}
-
/* A single dictionary entry. Since all entries will be allocated once
* during cache creation, those entries might be either used or unused.
* An entry is used if and only if it is contained in the doubly-linked
@@ -360,7 +383,7 @@ typedef struct entry_t
* above ensures that there will be no overflows.
* Only valid for used entries.
*/
- apr_uint32_t size;
+ apr_size_t size;
/* Number of (read) hits for this entry. Will be reset upon write.
* Only valid for used entries.
@@ -1122,17 +1145,19 @@ insert_entry(svn_membuffer_t *cache, ent
*/
static apr_uint32_t
get_group_index(svn_membuffer_t **cache,
- entry_key_t key)
+ const entry_key_t *key)
{
svn_membuffer_t *segment0 = *cache;
+ apr_uint64_t key0 = key->fingerprint[0];
+ apr_uint64_t key1 = key->fingerprint[1];
/* select the cache segment to use. they have all the same group_count.
* Since key may not be well-distributed, pre-fold it to a smaller but
* "denser" ranger. The modulus is a prime larger than the largest
* counts. */
- *cache = &segment0[(key[1] % APR_UINT64_C(2809637) + (key[0] / 37))
+ *cache = &segment0[(key1 % APR_UINT64_C(2809637) + (key0 / 37))
& (segment0->segment_count - 1)];
- return (key[0] % APR_UINT64_C(5030895599)) % segment0->group_count;
+ return (key0 % APR_UINT64_C(5030895599)) % segment0->group_count;
}
/* Reduce the hit count of ENTRY and update the accumulated hit info
@@ -1153,6 +1178,17 @@ let_entry_age(svn_membuffer_t *cache, en
}
}
+/* Return whether the keys in LHS and RHS match.
+ */
+static svn_boolean_t
+entry_keys_match(const entry_key_t *lhs,
+ const entry_key_t *rhs)
+{
+ return (lhs->fingerprint[0] == rhs->fingerprint[0])
+ && (lhs->fingerprint[1] == rhs->fingerprint[1])
+ && (lhs->key_len == rhs->key_len);
+}
+
/* Given the GROUP_INDEX that shall contain an entry with the hash key
* TO_FIND, find that entry in the specified group.
*
@@ -1164,11 +1200,15 @@ let_entry_age(svn_membuffer_t *cache, en
* new content), an unused entry or a forcibly removed entry (if all
* group entries are currently in use). The entries' hash value will be
* initialized with TO_FIND.
+ *
+ * Note: This function requires the caller to appropriately lock the CACHE.
+ * For FIND_EMPTY==FALSE, a read lock is required, for FIND_EMPTY==TRUE,
+ * the write lock must have been acquired.
*/
static entry_t *
find_entry(svn_membuffer_t *cache,
apr_uint32_t group_index,
- const apr_uint64_t to_find[2],
+ const full_key_t *to_find,
svn_boolean_t find_empty)
{
entry_group_t *group;
@@ -1189,8 +1229,7 @@ find_entry(svn_membuffer_t *cache,
entry = &group->entries[0];
/* initialize entry for the new key */
- entry->key[0] = to_find[0];
- entry->key[1] = to_find[1];
+ entry->key = to_find->entry_key;
}
return entry;
@@ -1201,14 +1240,28 @@ find_entry(svn_membuffer_t *cache,
while (1)
{
for (i = 0; i < group->header.used; ++i)
- if ( to_find[0] == group->entries[i].key[0]
- && to_find[1] == group->entries[i].key[1])
+ if (entry_keys_match(&group->entries[i].key, &to_find->entry_key))
{
- /* found it
- */
+ /* This is the only entry that _may_ contain the correct data. */
entry = &group->entries[i];
+
+ /* If we want to preserve it, check that it is actual a match. */
if (!find_empty)
- return entry;
+ {
+ /* If there is no full key to compare, we are done. */
+ if (!entry->key.key_len)
+ return entry;
+
+ /* Compare the full key. */
+ if (memcmp(to_find->full_key.data,
+ cache->data + entry->offset,
+ entry->key.key_len) == 0)
+ return entry;
+
+ /* Key conflict. The entry to find cannot be anywhere else.
+ * Therefore, it is not cached. */
+ return NULL;
+ }
/* need to empty that entry */
drop_entry(cache, entry);
@@ -1218,6 +1271,8 @@ find_entry(svn_membuffer_t *cache,
group = last_group_in_chain(cache,
&cache->directory[group_index]);
+ /* No entry found (actually, none left to find). */
+ entry = NULL;
break;
}
@@ -1300,8 +1355,7 @@ find_entry(svn_membuffer_t *cache,
/* initialize entry for the new key
*/
entry = &group->entries[group->header.used];
- entry->key[0] = to_find[0];
- entry->key[1] = to_find[1];
+ entry->key = to_find->entry_key;
}
return entry;
@@ -1883,7 +1937,7 @@ svn_cache__membuffer_clear(svn_membuffer
static svn_error_t *
entry_exists_internal(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
svn_boolean_t *found)
{
*found = find_entry(cache, group_index, to_find, FALSE) != NULL;
@@ -1896,7 +1950,7 @@ entry_exists_internal(svn_membuffer_t *c
static svn_error_t *
entry_exists(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
svn_boolean_t *found)
{
WITH_READ_LOCK(cache,
@@ -1929,9 +1983,9 @@ select_level(svn_membuffer_t *cache,
&& priority > SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY)
{
/* Large but important items go into L2. */
- entry_t dummy_entry = { { 0 } };
+ entry_t dummy_entry = { { { 0 } } };
dummy_entry.priority = priority;
- dummy_entry.size = (apr_uint32_t) size;
+ dummy_entry.size = size;
return ensure_data_insertable_l2(cache, &dummy_entry)
? &cache->l2
@@ -1942,9 +1996,9 @@ select_level(svn_membuffer_t *cache,
return NULL;
}
-/* Try to insert the serialized item given in BUFFER with SIZE into
- * the group GROUP_INDEX of CACHE and uniquely identify it by hash
- * value TO_FIND.
+/* Try to insert the serialized item given in BUFFER with ITEM_SIZE
+ * into the group GROUP_INDEX of CACHE and uniquely identify it by
+ * hash value TO_FIND.
*
* However, there is no guarantee that it will actually be put into
* the cache. If there is already some data associated with TO_FIND,
@@ -1952,19 +2006,20 @@ select_level(svn_membuffer_t *cache,
* be inserted.
*
* Note: This function requires the caller to serialization access.
- * Don't call it directly, call membuffer_cache_get_partial instead.
+ * Don't call it directly, call membuffer_cache_set instead.
*/
static svn_error_t *
membuffer_cache_set_internal(svn_membuffer_t *cache,
- entry_key_t to_find,
+ const full_key_t *to_find,
apr_uint32_t group_index,
char *buffer,
- apr_size_t size,
+ apr_size_t item_size,
apr_uint32_t priority,
DEBUG_CACHE_MEMBUFFER_TAG_ARG
apr_pool_t *scratch_pool)
{
cache_level_t *level;
+ apr_size_t size = item_size + to_find->entry_key.key_len;
/* first, look for a previous entry for the given key */
entry_t *entry = find_entry(cache, group_index, to_find, FALSE);
@@ -1978,20 +2033,24 @@ membuffer_cache_set_internal(svn_membuff
* negative value.
*/
cache->data_used += (apr_uint64_t)size - entry->size;
- entry->size = (apr_uint32_t) size;
+ entry->size = size;
entry->priority = priority;
#ifdef SVN_DEBUG_CACHE_MEMBUFFER
/* Remember original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag, buffer, size, scratch_pool));
+ SVN_ERR(store_content_part(tag, buffer, item_size, scratch_pool));
memcpy(&entry->tag, tag, sizeof(*tag));
#endif
- if (size)
- memcpy(cache->data + entry->offset, buffer, size);
+ if (entry->key.key_len)
+ memcpy(cache->data + entry->offset, to_find->full_key.data,
+ entry->key.key_len);
+ if (item_size)
+ memcpy(cache->data + entry->offset + entry->key.key_len, buffer,
+ item_size);
cache->total_writes++;
return SVN_NO_ERROR;
@@ -2007,7 +2066,7 @@ membuffer_cache_set_internal(svn_membuff
* the serialized item's (future) position within data buffer.
*/
entry = find_entry(cache, group_index, to_find, TRUE);
- entry->size = (apr_uint32_t) size;
+ entry->size = size;
entry->offset = level->current_data;
entry->priority = priority;
@@ -2015,7 +2074,7 @@ membuffer_cache_set_internal(svn_membuff
/* Remember original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag, buffer, size, scratch_pool));
+ SVN_ERR(store_content_part(tag, buffer, item_size, scratch_pool));
memcpy(&entry->tag, tag, sizeof(*tag));
#endif
@@ -2026,8 +2085,12 @@ membuffer_cache_set_internal(svn_membuff
/* Copy the serialized item data into the cache.
*/
- if (size)
- memcpy(cache->data + entry->offset, buffer, size);
+ if (entry->key.key_len)
+ memcpy(cache->data + entry->offset, to_find->full_key.data,
+ entry->key.key_len);
+ if (item_size)
+ memcpy(cache->data + entry->offset + entry->key.key_len, buffer,
+ item_size);
cache->total_writes++;
}
@@ -2056,7 +2119,7 @@ membuffer_cache_set_internal(svn_membuff
*/
static svn_error_t *
membuffer_cache_set(svn_membuffer_t *cache,
- entry_key_t key,
+ const full_key_t *key,
void *item,
svn_cache__serialize_func_t serializer,
apr_uint32_t priority,
@@ -2069,7 +2132,7 @@ membuffer_cache_set(svn_membuffer_t *cac
/* find the entry group that will hold the key.
*/
- group_index = get_group_index(&cache, key);
+ group_index = get_group_index(&cache, &key->entry_key);
/* Serialize data data.
*/
@@ -2112,12 +2175,12 @@ increment_hit_counters(svn_membuffer_t *
* be done in POOL.
*
* Note: This function requires the caller to serialization access.
- * Don't call it directly, call membuffer_cache_get_partial instead.
+ * Don't call it directly, call membuffer_cache_get instead.
*/
static svn_error_t *
membuffer_cache_get_internal(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
char **buffer,
apr_size_t *item_size,
DEBUG_CACHE_MEMBUFFER_TAG_ARG
@@ -2140,9 +2203,9 @@ membuffer_cache_get_internal(svn_membuff
return SVN_NO_ERROR;
}
- size = ALIGN_VALUE(entry->size);
+ size = ALIGN_VALUE(entry->size) - entry->key.key_len;
*buffer = ALIGN_POINTER(apr_palloc(result_pool, size + ITEM_ALIGNMENT-1));
- memcpy(*buffer, (const char*)cache->data + entry->offset, size);
+ memcpy(*buffer, cache->data + entry->offset + entry->key.key_len, size);
#ifdef SVN_DEBUG_CACHE_MEMBUFFER
@@ -2154,7 +2217,8 @@ membuffer_cache_get_internal(svn_membuff
/* Compare original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag, *buffer, entry->size, result_pool));
+ SVN_ERR(store_content_part(tag, *buffer, entry->size - entry->key.key_len,
+ result_pool));
SVN_ERR(assert_equal_tags(&entry->tag, tag));
#endif
@@ -2162,7 +2226,7 @@ membuffer_cache_get_internal(svn_membuff
/* update hit statistics
*/
increment_hit_counters(cache, entry);
- *item_size = entry->size;
+ *item_size = entry->size - entry->key.key_len;
return SVN_NO_ERROR;
}
@@ -2174,7 +2238,7 @@ membuffer_cache_get_internal(svn_membuff
*/
static svn_error_t *
membuffer_cache_get(svn_membuffer_t *cache,
- entry_key_t key,
+ const full_key_t *key,
void **item,
svn_cache__deserialize_func_t deserializer,
DEBUG_CACHE_MEMBUFFER_TAG_ARG
@@ -2186,7 +2250,7 @@ membuffer_cache_get(svn_membuffer_t *cac
/* find the entry group that will hold the key.
*/
- group_index = get_group_index(&cache, key);
+ group_index = get_group_index(&cache, &key->entry_key);
WITH_READ_LOCK(cache,
membuffer_cache_get_internal(cache,
group_index,
@@ -2214,7 +2278,7 @@ membuffer_cache_get(svn_membuffer_t *cac
static svn_error_t *
membuffer_cache_has_key_internal(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
svn_boolean_t *found)
{
entry_t *entry = find_entry(cache, group_index, to_find, FALSE);
@@ -2243,12 +2307,12 @@ membuffer_cache_has_key_internal(svn_mem
*/
static svn_error_t *
membuffer_cache_has_key(svn_membuffer_t *cache,
- entry_key_t key,
+ const full_key_t *key,
svn_boolean_t *found)
{
/* find the entry group that will hold the key.
*/
- apr_uint32_t group_index = get_group_index(&cache, key);
+ apr_uint32_t group_index = get_group_index(&cache, &key->entry_key);
cache->total_reads++;
WITH_READ_LOCK(cache,
@@ -2274,7 +2338,7 @@ membuffer_cache_has_key(svn_membuffer_t
static svn_error_t *
membuffer_cache_get_partial_internal(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
void **item,
svn_boolean_t *found,
svn_cache__partial_getter_func_t deserializer,
@@ -2293,6 +2357,8 @@ membuffer_cache_get_partial_internal(svn
}
else
{
+ const void *item_data = cache->data + entry->offset + entry->key.key_len;
+ apr_size_t item_size = entry->size - entry->key.key_len;
*found = TRUE;
increment_hit_counters(cache, entry);
@@ -2306,19 +2372,12 @@ membuffer_cache_get_partial_internal(svn
/* Compare original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag,
- (const char*)cache->data + entry->offset,
- entry->size,
- result_pool));
+ SVN_ERR(store_content_part(tag, item_data, item_size, result_pool));
SVN_ERR(assert_equal_tags(&entry->tag, tag));
#endif
- return deserializer(item,
- (const char*)cache->data + entry->offset,
- entry->size,
- baton,
- result_pool);
+ return deserializer(item, item_data, item_size, baton, result_pool);
}
}
@@ -2330,7 +2389,7 @@ membuffer_cache_get_partial_internal(svn
*/
static svn_error_t *
membuffer_cache_get_partial(svn_membuffer_t *cache,
- entry_key_t key,
+ const full_key_t *key,
void **item,
svn_boolean_t *found,
svn_cache__partial_getter_func_t deserializer,
@@ -2338,7 +2397,7 @@ membuffer_cache_get_partial(svn_membuffe
DEBUG_CACHE_MEMBUFFER_TAG_ARG
apr_pool_t *result_pool)
{
- apr_uint32_t group_index = get_group_index(&cache, key);
+ apr_uint32_t group_index = get_group_index(&cache, &key->entry_key);
WITH_READ_LOCK(cache,
membuffer_cache_get_partial_internal
@@ -2362,7 +2421,7 @@ membuffer_cache_get_partial(svn_membuffe
static svn_error_t *
membuffer_cache_set_partial_internal(svn_membuffer_t *cache,
apr_uint32_t group_index,
- entry_key_t to_find,
+ const full_key_t *to_find,
svn_cache__partial_setter_func_t func,
void *baton,
DEBUG_CACHE_MEMBUFFER_TAG_ARG
@@ -2380,9 +2439,10 @@ membuffer_cache_set_partial_internal(svn
svn_error_t *err;
/* access the serialized cache item */
- char *data = (char*)cache->data + entry->offset;
- char *orig_data = data;
- apr_size_t size = entry->size;
+ apr_size_t key_len = entry->key.key_len;
+ void *item_data = cache->data + entry->offset + key_len;
+ void *orig_data = item_data;
+ apr_size_t item_size = entry->size - key_len;
increment_hit_counters(cache, entry);
cache->total_writes++;
@@ -2392,19 +2452,19 @@ membuffer_cache_set_partial_internal(svn
/* Check for overlapping entries.
*/
SVN_ERR_ASSERT(entry->next == NO_INDEX ||
- entry->offset + size
+ entry->offset + entry->size
<= get_entry(cache, entry->next)->offset);
/* Compare original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag, data, size, scratch_pool));
+ SVN_ERR(store_content_part(tag, item_data, item_size, scratch_pool));
SVN_ERR(assert_equal_tags(&entry->tag, tag));
#endif
/* modify it, preferably in-situ.
*/
- err = func((void **)&data, &size, baton, scratch_pool);
+ err = func(&item_data, &item_size, baton, scratch_pool);
if (err)
{
@@ -2421,21 +2481,26 @@ membuffer_cache_set_partial_internal(svn
/* if the modification caused a re-allocation, we need to remove
* the old entry and to copy the new data back into cache.
*/
- if (data != orig_data)
+ if (item_data != orig_data)
{
/* Remove the old entry and try to make space for the new one.
*/
drop_entry(cache, entry);
- if ( (cache->max_entry_size >= size)
- && ensure_data_insertable_l1(cache, size))
+ if ( (cache->max_entry_size >= item_size + key_len)
+ && ensure_data_insertable_l1(cache, item_size + key_len))
{
/* Write the new entry.
*/
entry = find_entry(cache, group_index, to_find, TRUE);
- entry->size = (apr_uint32_t) size;
+ entry->size = item_size + key_len;
entry->offset = cache->l1.current_data;
- if (size)
- memcpy(cache->data + entry->offset, data, size);
+
+ if (key_len)
+ memcpy(cache->data + entry->offset,
+ to_find->full_key.data, key_len);
+ if (item_size)
+ memcpy(cache->data + entry->offset + key_len, item_data,
+ item_size);
/* Link the entry properly.
*/
@@ -2447,7 +2512,7 @@ membuffer_cache_set_partial_internal(svn
/* Remember original content, type and key (hashes)
*/
- SVN_ERR(store_content_part(tag, data, size, scratch_pool));
+ SVN_ERR(store_content_part(tag, item_data, item_size, scratch_pool));
memcpy(&entry->tag, tag, sizeof(*tag));
#endif
@@ -2464,7 +2529,7 @@ membuffer_cache_set_partial_internal(svn
*/
static svn_error_t *
membuffer_cache_set_partial(svn_membuffer_t *cache,
- entry_key_t key,
+ const full_key_t *key,
svn_cache__partial_setter_func_t func,
void *baton,
DEBUG_CACHE_MEMBUFFER_TAG_ARG
@@ -2472,7 +2537,7 @@ membuffer_cache_set_partial(svn_membuffe
{
/* cache item lookup
*/
- apr_uint32_t group_index = get_group_index(&cache, key);
+ apr_uint32_t group_index = get_group_index(&cache, &key->entry_key);
WITH_WRITE_LOCK(cache,
membuffer_cache_set_partial_internal
(cache, group_index, key, func, baton,
@@ -2498,22 +2563,6 @@ membuffer_cache_set_partial(svn_membuffe
* svn_cache__t instance.
*/
-/* Stores the combined key value for the given key. It will be used by
- * combine_key() to short-circuit expensive hash calculations.
- */
-typedef struct last_access_key_t
-{
- /* result of key combining */
- entry_key_t combined_key;
-
- /* length of the key (or APR_HASH_KEY_STRING if not used) */
- apr_ssize_t key_len;
-
- /* the original key. Only KEY_LEN bytes are valid. We use uint32 for
- * better compatibility with pseudo-md5 functions. */
- apr_uint32_t key[64];
-} last_access_key_t;
-
/* Internal cache structure (used in svn_cache__t.cache_internal) basically
* holding the additional parameters needed to call the respective membuffer
* functions.
@@ -2533,15 +2582,10 @@ typedef struct svn_membuffer_cache_t
svn_cache__deserialize_func_t deserializer;
/* Prepend this byte sequence to any key passed to us.
- * This makes (very likely) our keys different from all keys used
- * by other svn_membuffer_cache_t instances.
- */
- entry_key_t prefix;
-
- /* The tail of the prefix string. It is being used as a developer-visible
- * ID for this cache instance.
+ * This makes our keys different from all keys used by svn_membuffer_cache_t
+ * instances that we don't want to share cached data with.
*/
- char info_prefix[PREFIX_TAIL_LEN];
+ full_key_t prefix;
/* length of the keys that will be passed to us through the
* svn_cache_t interface. May be APR_HASH_KEY_STRING.
@@ -2553,23 +2597,13 @@ typedef struct svn_membuffer_cache_t
/* Temporary buffer containing the hash key for the current access
*/
- entry_key_t combined_key;
-
- /* cache for the last key used.
- * Will be NULL for caches with short fix-sized keys.
- */
- last_access_key_t *last_access;
+ full_key_t combined_key;
/* if enabled, this will serialize the access to this instance.
*/
svn_mutex__t *mutex;
} svn_membuffer_cache_t;
-/* After an estimated ALLOCATIONS_PER_POOL_CLEAR allocations, we should
- * clear the svn_membuffer_cache_t.pool to keep memory consumption in check.
- */
-#define ALLOCATIONS_PER_POOL_CLEAR 10
-
/* Basically calculate a hash value for KEY of length KEY_LEN, combine it
* with the CACHE->PREFIX and write the result in CACHE->COMBINED_KEY.
* This could replace combine_key() entirely but we actually use it only
@@ -2580,70 +2614,35 @@ combine_long_key(svn_membuffer_cache_t *
const void *key,
apr_ssize_t key_len)
{
- assert(cache->last_access);
+ apr_uint32_t *digest_buffer;
+ char *key_copy;
+ apr_size_t prefix_len = cache->prefix.entry_key.key_len;
+ apr_size_t aligned_key_len;
/* handle variable-length keys */
if (key_len == APR_HASH_KEY_STRING)
key_len = strlen((const char *) key);
- /* same key as the last time? -> short-circuit */
- if ( key_len == cache->last_access->key_len
- && memcmp(key, cache->last_access->key, key_len) == 0)
- {
- memcpy(cache->combined_key, cache->last_access->combined_key,
- sizeof(cache->combined_key));
- }
- else if (key_len >= 64)
- {
- /* relatively long key. Use the generic, slow hash code for it */
- apr_md5((unsigned char*)cache->combined_key, key, key_len);
- cache->combined_key[0] ^= cache->prefix[0];
- cache->combined_key[1] ^= cache->prefix[1];
-
- /* is the key short enough to cache the result? */
- if (key_len <= sizeof(cache->last_access->key))
- {
- memcpy(cache->last_access->combined_key, cache->combined_key,
- sizeof(cache->combined_key));
- cache->last_access->key_len = key_len;
- memcpy(cache->last_access->key, key, key_len);
- }
- }
- else
- {
- /* shorter keys use efficient hash code and *do* cache the results */
- cache->last_access->key_len = key_len;
- if (key_len < 16)
- {
- memset(cache->last_access->key, 0, 16);
- memcpy(cache->last_access->key, key, key_len);
-
- svn__pseudo_md5_15((apr_uint32_t *)cache->combined_key,
- cache->last_access->key);
- }
- else if (key_len < 32)
- {
- memset(cache->last_access->key, 0, 32);
- memcpy(cache->last_access->key, key, key_len);
+ aligned_key_len = ALIGN_VALUE(key_len);
- svn__pseudo_md5_31((apr_uint32_t *)cache->combined_key,
- cache->last_access->key);
- }
- else
- {
- memset(cache->last_access->key, 0, 64);
- memcpy(cache->last_access->key, key, key_len);
-
- svn__pseudo_md5_63((apr_uint32_t *)cache->combined_key,
- cache->last_access->key);
- }
-
- cache->combined_key[0] ^= cache->prefix[0];
- cache->combined_key[1] ^= cache->prefix[1];
-
- memcpy(cache->last_access->combined_key, cache->combined_key,
- sizeof(cache->combined_key));
- }
+ /* Combine keys. */
+ svn_membuf__ensure(&cache->combined_key.full_key,
+ aligned_key_len + prefix_len);
+
+ key_copy = (char *)cache->combined_key.full_key.data + prefix_len;
+ cache->combined_key.entry_key.key_len = aligned_key_len + prefix_len;
+ memcpy(key_copy, key, key_len);
+ memset(key_copy + key_len, 0, aligned_key_len - key_len);
+
+ /* Hash key into 16 bytes. */
+ digest_buffer = (apr_uint32_t *)cache->combined_key.entry_key.fingerprint;
+ svn__fnv1a_32x4_raw(digest_buffer, key, key_len);
+
+ /* Combine with prefix. */
+ cache->combined_key.entry_key.fingerprint[0]
+ ^= cache->prefix.entry_key.fingerprint[0];
+ cache->combined_key.entry_key.fingerprint[1]
+ ^= cache->prefix.entry_key.fingerprint[1];
}
/* Basically calculate a hash value for KEY of length KEY_LEN, combine it
@@ -2654,42 +2653,40 @@ combine_key(svn_membuffer_cache_t *cache
const void *key,
apr_ssize_t key_len)
{
- /* copy of *key, padded with 0 */
- apr_uint64_t data[2];
-
/* short, fixed-size keys are the most common case */
- if (key_len == 16)
- {
- data[0] = ((const apr_uint64_t *)key)[0];
- data[1] = ((const apr_uint64_t *)key)[1];
- }
- else if (key_len == 8)
- {
- data[0] = ((const apr_uint64_t *)key)[0];
- data[1] = 0;
- }
- else if (key_len != APR_HASH_KEY_STRING && key_len < 16)
+ if (key_len != APR_HASH_KEY_STRING && key_len <= 16)
{
+ const apr_size_t prefix_len = cache->prefix.entry_key.key_len;
+
+ /* Copy of *key, padded with 0.
+ * We put it just behind the prefix already copied into the COMBINED_KEY.
+ * The buffer space has been allocated when the cache was created. */
+ apr_uint64_t *data = (void *)((char *)cache->combined_key.full_key.data +
+ prefix_len);
+ assert(prefix_len <= cache->combined_key.full_key.size - 16);
+ cache->combined_key.entry_key.key_len = prefix_len + 16;
+
data[0] = 0;
data[1] = 0;
memcpy(data, key, key_len);
+
+ /* scramble key DATA. All of this must be reversible to prevent key
+ * collisions. So, we limit ourselves to xor and permutations. */
+ data[1] = (data[1] << 27) | (data[1] >> 37);
+ data[1] ^= data[0] & 0xffff;
+ data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);
+
+ /* combine with this cache's namespace */
+ cache->combined_key.entry_key.fingerprint[0]
+ = data[0] ^ cache->prefix.entry_key.fingerprint[0];
+ cache->combined_key.entry_key.fingerprint[1]
+ = data[1] ^ cache->prefix.entry_key.fingerprint[1];
}
else
{
/* longer or variably sized keys */
combine_long_key(cache, key, key_len);
- return;
}
-
- /* scramble key DATA. All of this must be reversible to prevent key
- * collisions. So, we limit ourselves to xor and permutations. */
- data[1] = (data[1] << 27) | (data[1] >> 37);
- data[1] ^= data[0] & 0xffff;
- data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);
-
- /* combine with this cache's namespace */
- cache->combined_key[0] = data[0] ^ cache->prefix[0];
- cache->combined_key[1] = data[1] ^ cache->prefix[1];
}
/* Implement svn_cache__vtable_t.get (not thread-safe)
@@ -2721,7 +2718,7 @@ svn_membuffer_cache_get(void **value_p,
/* Look the item up. */
SVN_ERR(membuffer_cache_get(cache->membuffer,
- cache->combined_key,
+ &cache->combined_key,
value_p,
cache->deserializer,
DEBUG_CACHE_MEMBUFFER_TAG
@@ -2758,7 +2755,7 @@ svn_membuffer_cache_has_key(svn_boolean_
/* Look the item up. */
SVN_ERR(membuffer_cache_has_key(cache->membuffer,
- cache->combined_key,
+ &cache->combined_key,
found));
/* return result */
@@ -2790,7 +2787,7 @@ svn_membuffer_cache_set(void *cache_void
* that the item will actually be cached afterwards.
*/
return membuffer_cache_set(cache->membuffer,
- cache->combined_key,
+ &cache->combined_key,
value,
cache->serializer,
cache->priority,
@@ -2836,7 +2833,7 @@ svn_membuffer_cache_get_partial(void **v
combine_key(cache, key, cache->key_len);
SVN_ERR(membuffer_cache_get_partial(cache->membuffer,
- cache->combined_key,
+ &cache->combined_key,
value_p,
found,
func,
@@ -2864,7 +2861,7 @@ svn_membuffer_cache_set_partial(void *ca
{
combine_key(cache, key, cache->key_len);
SVN_ERR(membuffer_cache_set_partial(cache->membuffer,
- cache->combined_key,
+ &cache->combined_key,
func,
baton,
DEBUG_CACHE_MEMBUFFER_TAG
@@ -2936,7 +2933,7 @@ svn_membuffer_cache_get_info(void *cache
/* cache front-end specific data */
- info->id = apr_pstrdup(result_pool, cache->info_prefix);
+ info->id = apr_pstrdup(result_pool, cache->prefix.full_key.data);
/* collect info from shared cache back-end */
@@ -3129,11 +3126,12 @@ svn_cache__create_membuffer_cache(svn_ca
apr_pool_t *scratch_pool)
{
svn_checksum_t *checksum;
+ apr_size_t prefix_len, prefix_orig_len;
/* allocate the cache header structures
*/
svn_cache__t *wrapper = apr_pcalloc(result_pool, sizeof(*wrapper));
- svn_membuffer_cache_t *cache = apr_palloc(result_pool, sizeof(*cache));
+ svn_membuffer_cache_t *cache = apr_pcalloc(result_pool, sizeof(*cache));
/* initialize our internal cache header
*/
@@ -3144,33 +3142,38 @@ svn_cache__create_membuffer_cache(svn_ca
cache->deserializer = deserializer
? deserializer
: deserialize_svn_stringbuf;
- get_prefix_tail(prefix, cache->info_prefix);
cache->priority = priority;
cache->key_len = klen;
SVN_ERR(svn_mutex__init(&cache->mutex, thread_safe, result_pool));
- /* for performance reasons, we don't actually store the full prefix but a
- * hash value of it
- */
+ /* Copy the prefix into the prefix full key. Align it to ITEM_ALIGMENT.
+ * Don't forget to include the terminating NUL. */
+ prefix_orig_len = strlen(prefix) + 1;
+ prefix_len = ALIGN_VALUE(prefix_orig_len);
+
+ svn_membuf__create(&cache->prefix.full_key, prefix_len, result_pool);
+ memcpy((char *)cache->prefix.full_key.data, prefix, prefix_orig_len);
+ memset((char *)cache->prefix.full_key.data + prefix_orig_len, 0,
+ prefix_len - prefix_orig_len);
+
+ /* Construct the folded prefix key. */
SVN_ERR(svn_checksum(&checksum,
svn_checksum_md5,
prefix,
strlen(prefix),
scratch_pool));
- memcpy(cache->prefix, checksum->digest, sizeof(cache->prefix));
-
- /* fix-length keys of 16 bytes or under don't need a buffer because we
- * can use a very fast key combining algorithm. */
- if ((klen == APR_HASH_KEY_STRING) || klen > sizeof(entry_key_t))
- {
- cache->last_access = apr_pcalloc(result_pool, sizeof(*cache->last_access));
- cache->last_access->key_len = APR_HASH_KEY_STRING;
- }
- else
- {
- cache->last_access = NULL;
- }
+ memcpy(cache->prefix.entry_key.fingerprint, checksum->digest,
+ sizeof(cache->prefix.entry_key.fingerprint));
+ cache->prefix.entry_key.key_len = prefix_len;
+
+ /* Initialize the combined key. Pre-allocate some extra room in the full
+ * key such that we probably don't need to re-alloc. */
+ cache->combined_key.entry_key = cache->prefix.entry_key;
+ svn_membuf__create(&cache->combined_key.full_key, prefix_len + 200,
+ result_pool);
+ memcpy(cache->combined_key.full_key.data, cache->prefix.full_key.data,
+ prefix_len);
/* initialize the generic cache wrapper
*/
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/checksum.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/checksum.c Tue May 26 08:57:33 2015
@@ -347,7 +347,10 @@ svn_checksum_deserialize(const svn_check
apr_size_t prefix_len = strlen(ckind_str[0]);
/* "$md5 $...", "$sha1$..." or ... */
- SVN_ERR_ASSERT(strlen(data) > prefix_len);
+ if (strlen(data) <= prefix_len)
+ return svn_error_createf(SVN_ERR_BAD_CHECKSUM_PARSE, NULL,
+ _("Invalid prefix in checksum '%s'"),
+ data);
for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind)
if (strncmp(ckind_str[kind], data, prefix_len) == 0)
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/cmdline.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/cmdline.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/cmdline.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/cmdline.c Tue May 26 08:57:33 2015
@@ -1529,3 +1529,50 @@ svn_cmdline__edit_string_externally(svn_
return svn_error_trace(err);
}
+
+svn_error_t *
+svn_cmdline__parse_trust_options(
+ svn_boolean_t *trust_server_cert_unknown_ca,
+ svn_boolean_t *trust_server_cert_cn_mismatch,
+ svn_boolean_t *trust_server_cert_expired,
+ svn_boolean_t *trust_server_cert_not_yet_valid,
+ svn_boolean_t *trust_server_cert_other_failure,
+ const char *opt_arg,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *failures;
+ int i;
+
+ *trust_server_cert_unknown_ca = FALSE;
+ *trust_server_cert_cn_mismatch = FALSE;
+ *trust_server_cert_expired = FALSE;
+ *trust_server_cert_not_yet_valid = FALSE;
+ *trust_server_cert_other_failure = FALSE;
+
+ failures = svn_cstring_split(opt_arg, ", \n\r\t\v", TRUE, scratch_pool);
+
+ for (i = 0; i < failures->nelts; i++)
+ {
+ const char *value = APR_ARRAY_IDX(failures, i, const char *);
+ if (!strcmp(value, "unknown-ca"))
+ *trust_server_cert_unknown_ca = TRUE;
+ else if (!strcmp(value, "cn-mismatch"))
+ *trust_server_cert_cn_mismatch = TRUE;
+ else if (!strcmp(value, "expired"))
+ *trust_server_cert_expired = TRUE;
+ else if (!strcmp(value, "not-yet-valid"))
+ *trust_server_cert_not_yet_valid = TRUE;
+ else if (!strcmp(value, "other"))
+ *trust_server_cert_other_failure = TRUE;
+ else
+ return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Unknown value '%s' for %s.\n"
+ "Supported values: %s"),
+ value,
+ "--trust-server-cert-failures",
+ "unknown-ca, cn-mismatch, expired, "
+ "not-yet-valid, other");
+ }
+
+ return SVN_NO_ERROR;
+}
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/config_file.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/config_file.c Tue May 26 08:57:33 2015
@@ -940,7 +940,6 @@ svn_config_ensure(const char *config_dir
"### HTTP operation." NL
"### http-chunked-requests Whether to use chunked transfer" NL
"### encoding for HTTP requests body." NL
- "### neon-debug-mask Debug mask for Neon HTTP library" NL
"### ssl-authority-files List of files, each of a trusted CA"
NL
"### ssl-trust-default-ca Trust the system 'default' CAs" NL
@@ -1033,7 +1032,6 @@ svn_config_ensure(const char *config_dir
"### Most users will not need to explicitly set the http-library" NL
"### option, but valid values for the option include:" NL
"### 'serf': Serf-based module (Subversion 1.5 - present)" NL
- "### 'neon': Neon-based module (Subversion 1.0 - 1.7)" NL
"### Availability of these modules may depend on your specific" NL
"### Subversion distribution." NL
"###" NL
@@ -1058,7 +1056,6 @@ svn_config_ensure(const char *config_dir
"# http-proxy-username = blah" NL
"# http-proxy-password = doubleblah" NL
"# http-timeout = 60" NL
- "# neon-debug-mask = 130" NL
#ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE
"# store-plaintext-passwords = no" NL
#endif
@@ -1099,7 +1096,6 @@ svn_config_ensure(const char *config_dir
"# http-proxy-password = defaultpassword" NL
"# http-compression = no" NL
"# No http-timeout, so just use the builtin default." NL
- "# No neon-debug-mask, so neon debugging is disabled." NL
"# ssl-authority-files = /path/to/CAcert.pem;/path/to/CAcert2.pem" NL
"#" NL
"# Password / passphrase caching parameters:" NL
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.c Tue May 26 08:57:33 2015
@@ -132,6 +132,25 @@ svn__fnv1a_32x4(const void *input, apr_s
len - processed);
}
+void
+svn__fnv1a_32x4_raw(apr_uint32_t hashes[4],
+ const void *input,
+ apr_size_t len)
+{
+ apr_size_t processed;
+
+ apr_size_t i;
+ for (i = 0; i < SCALING; ++i)
+ hashes[i] = FNV1_BASE_32;
+
+ /* Process full 16 byte chunks. */
+ processed = fnv1a_32x4(hashes, input, len);
+
+ /* Fold the remainder (if any) into the first hash. */
+ hashes[0] = fnv1a_32(hashes[0], (const char *)input + processed,
+ len - processed);
+}
+
struct svn_fnv1a_32__context_t
{
apr_uint32_t hash;
Modified: subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.h
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.h?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.h (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_subr/fnv1a.h Tue May 26 08:57:33 2015
@@ -76,6 +76,14 @@ svn_fnv1a_32x4__update(svn_fnv1a_32x4__c
apr_uint32_t
svn_fnv1a_32x4__finalize(svn_fnv1a_32x4__context_t *context);
+/* Set HASHES to the 4 partial hash sums produced by the modified FVN-1a
+ * over INPUT of LEN bytes.
+ */
+void
+svn__fnv1a_32x4_raw(apr_uint32_t hashes[4],
+ const void *input,
+ apr_size_t len);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/move-tracking-2/subversion/libsvn_wc/externals.c Tue May 26 08:57:33 2015
@@ -462,9 +462,10 @@ struct edit_baton
const apr_array_header_t *ext_patterns;
const char *diff3cmd;
- const char *url;
const char *repos_root_url;
const char *repos_uuid;
+ const char *old_repos_relpath;
+ const char *new_repos_relpath;
const char *record_ancestor_abspath;
const char *recorded_repos_relpath;
@@ -474,6 +475,8 @@ struct edit_baton
/* Introducing a new file external */
svn_boolean_t added;
+ svn_wc_conflict_resolver_func2_t conflict_func;
+ void *conflict_baton;
svn_cancel_func_t cancel_func;
void *cancel_baton;
svn_wc_notify_func2_t notify_func;
@@ -572,7 +575,8 @@ open_file(const char *path,
*file_baton = eb;
SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision,
- NULL, NULL, NULL, &eb->changed_rev,
+ &eb->old_repos_relpath, NULL, NULL,
+ &eb->changed_rev,
&eb->changed_date, &eb->changed_author,
NULL, &eb->original_checksum, NULL, NULL,
&eb->had_props, NULL, NULL,
@@ -733,8 +737,6 @@ close_file(void *file_baton,
const svn_checksum_t *original_checksum = NULL;
svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision);
- const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
- eb->url, pool);
if (! added)
{
@@ -908,14 +910,14 @@ close_file(void *file_baton,
svn_wc_conflict_version_create2(
eb->repos_root_url,
eb->repos_uuid,
- repos_relpath,
+ eb->old_repos_relpath,
eb->original_revision,
svn_node_file,
pool),
svn_wc_conflict_version_create2(
eb->repos_root_url,
eb->repos_uuid,
- repos_relpath,
+ eb->new_repos_relpath,
*eb->target_revision,
svn_node_file,
pool),
@@ -933,7 +935,7 @@ close_file(void *file_baton,
eb->db,
eb->local_abspath,
eb->wri_abspath,
- repos_relpath,
+ eb->new_repos_relpath,
eb->repos_root_url,
eb->repos_uuid,
*eb->target_revision,
@@ -963,6 +965,18 @@ close_file(void *file_baton,
/* Run the work queue to complete the installation */
SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath,
eb->cancel_func, eb->cancel_baton, pool));
+
+ if (conflict_skel && eb->conflict_func)
+ SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db,
+ eb->local_abspath,
+ svn_node_file,
+ conflict_skel,
+ NULL /* merge_options */,
+ eb->conflict_func,
+ eb->conflict_baton,
+ eb->cancel_func,
+ eb->cancel_baton,
+ pool));
}
/* Notify */
@@ -1002,6 +1016,7 @@ close_edit(void *edit_baton,
if (!eb->file_closed)
{
+ apr_hash_t *wcroot_iprops = NULL;
/* The file wasn't updated, but its url or revision might have...
e.g. switch between branches for relative externals.
@@ -1009,53 +1024,26 @@ close_edit(void *edit_baton,
investigating when we should and shouldn't update it...
and avoid hard to debug edge cases */
- svn_node_kind_t kind;
- const char *old_repos_relpath;
- svn_revnum_t changed_rev;
- apr_time_t changed_date;
- const char *changed_author;
- const svn_checksum_t *checksum;
- apr_hash_t *pristine_props;
- const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
- eb->url, pool);
-
- SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
- NULL, NULL, &changed_rev, &changed_date,
- &changed_author, NULL, &checksum, NULL,
- NULL, NULL, &pristine_props, NULL,
- eb->db, eb->local_abspath,
- pool, pool));
+ if (eb->iprops)
+ {
+ wcroot_iprops = apr_hash_make(pool);
+ svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
+ }
- if (kind != svn_node_file)
- return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
- _("Node '%s' is no existing file external"),
- svn_dirent_local_style(eb->local_abspath,
- pool));
-
- SVN_ERR(svn_wc__db_external_add_file(
- eb->db,
- eb->local_abspath,
- eb->wri_abspath,
- repos_relpath,
- eb->repos_root_url,
- eb->repos_uuid,
- *eb->target_revision,
- pristine_props,
- eb->iprops,
- eb->changed_rev,
- eb->changed_date,
- eb->changed_author,
- checksum,
- NULL /* clear dav props */,
- eb->record_ancestor_abspath,
- eb->recorded_repos_relpath,
- eb->recorded_peg_revision,
- eb->recorded_revision,
- FALSE, NULL,
- TRUE /* keep_recorded_info */,
- NULL /* conflict_skel */,
- NULL /* work_items */,
- pool));
+ SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
+ eb->local_abspath,
+ svn_depth_infinity,
+ eb->new_repos_relpath,
+ eb->repos_root_url,
+ eb->repos_uuid,
+ *eb->target_revision,
+ apr_hash_make(pool)
+ /* exclude_relpaths */,
+ wcroot_iprops,
+ TRUE /* empty update */,
+ eb->notify_func,
+ eb->notify_baton,
+ pool));
}
return SVN_NO_ERROR;
@@ -1079,6 +1067,8 @@ svn_wc__get_file_external_editor(const s
const char *recorded_url,
const svn_opt_revision_t *recorded_peg_rev,
const svn_opt_revision_t *recorded_rev,
+ svn_wc_conflict_resolver_func2_t conflict_func,
+ void *conflict_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -1101,9 +1091,12 @@ svn_wc__get_file_external_editor(const s
eb->name = svn_dirent_basename(eb->local_abspath, NULL);
eb->target_revision = target_revision;
- eb->url = apr_pstrdup(edit_pool, url);
eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
+ eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url, edit_pool);
+ eb->old_repos_relpath = eb->new_repos_relpath;
+
+ eb->original_revision = SVN_INVALID_REVNUM;
eb->iprops = iprops;
@@ -1127,6 +1120,8 @@ svn_wc__get_file_external_editor(const s
else
eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */
+ eb->conflict_func = conflict_func;
+ eb->conflict_baton = conflict_baton;
eb->cancel_func = cancel_func;
eb->cancel_baton = cancel_baton;
eb->notify_func = notify_func;
Modified: subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/conflict-callbacks.c Tue May 26 08:57:33 2015
@@ -1130,6 +1130,8 @@ handle_tree_conflict(svn_wc_conflict_res
apr_pool_t *scratch_pool)
{
const char *readable_desc;
+ const char *src_left_version;
+ const char *src_right_version;
apr_pool_t *iterpool;
SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
@@ -1142,6 +1144,21 @@ handle_tree_conflict(svn_wc_conflict_res
scratch_pool),
readable_desc));
+ src_left_version =
+ svn_cl__node_description(desc->src_left_version,
+ desc->src_left_version->repos_url,
+ scratch_pool);
+ if (src_left_version)
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+ _("Source left"), src_left_version));
+ src_right_version =
+ svn_cl__node_description(desc->src_right_version,
+ desc->src_right_version->repos_url,
+ scratch_pool);
+ if (src_right_version)
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+ _("Source right"), src_right_version));
+
iterpool = svn_pool_create(scratch_pool);
while (1)
{
Modified: subversion/branches/move-tracking-2/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svn/svn.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svn/svn.c (original)
+++ subversion/branches/move-tracking-2/subversion/svn/svn.c Tue May 26 08:57:33 2015
@@ -125,11 +125,7 @@ typedef enum svn_cl__longopt_t {
opt_show_revs,
opt_reintegrate,
opt_trust_server_cert,
- opt_trust_server_cert_unknown_ca,
- opt_trust_server_cert_cn_mismatch,
- opt_trust_server_cert_expired,
- opt_trust_server_cert_not_yet_valid,
- opt_trust_server_cert_other_failure,
+ opt_trust_server_cert_failures,
opt_strip,
opt_ignore_keywords,
opt_reverse_diff,
@@ -243,29 +239,23 @@ const apr_getopt_option_t svn_cl__option
{"no-auth-cache", opt_no_auth_cache, 0,
N_("do not cache authentication tokens")},
{"trust-server-cert", opt_trust_server_cert, 0,
- N_("deprecated; same as --trust-unknown-ca")},
- {"trust-unknown-ca", opt_trust_server_cert_unknown_ca, 0,
- N_("with --non-interactive, accept SSL server\n"
+ N_("deprecated; same as\n"
" "
- "certificates from unknown certificate authorities")},
- {"trust-cn-mismatch", opt_trust_server_cert_cn_mismatch, 0,
+ "--trust-server-cert-failures=unknown-ca")},
+ {"trust-server-cert-failures", opt_trust_server_cert_failures, 1,
N_("with --non-interactive, accept SSL server\n"
" "
- "certificates even if the server hostname does not\n"
+ "certificates with failures; ARG is comma-separated\n"
" "
- "match the certificate's common name attribute")},
- {"trust-expired", opt_trust_server_cert_expired, 0,
- N_("with --non-interactive, accept expired SSL server\n"
+ "list of 'unknown-ca' (Unknown Authority),\n"
" "
- "certificates")},
- {"trust-not-yet-valid", opt_trust_server_cert_not_yet_valid, 0,
- N_("with --non-interactive, accept SSL server\n"
+ "'cn-mismatch' (Hostname mismatch), 'expired'\n"
" "
- "certificates from the future")},
- {"trust-other-failure", opt_trust_server_cert_other_failure, 0,
- N_("with --non-interactive, accept SSL server\n"
+ "(Expired certificate), 'not-yet-valid' (Not yet\n"
+ " "
+ "valid certificate) and 'other' (all other not\n"
" "
- "certificates with failures other than the above")},
+ "separately classified certificate errors).")},
{"non-interactive", opt_non_interactive, 0,
N_("do no interactive prompting (default is to prompt\n"
" "
@@ -408,7 +398,7 @@ const apr_getopt_option_t svn_cl__option
" "
"svn:externals properties")},
{"show-inherited-props", opt_show_inherited_props, 0,
- N_("retrieve target's inherited properties")},
+ N_("retrieve properties set on parents of the target")},
{"search", opt_search, 1,
N_("use ARG as search pattern (glob syntax)")},
{"search-and", opt_search_and, 1,
@@ -459,9 +449,7 @@ const apr_getopt_option_t svn_cl__option
const int svn_cl__global_options[] =
{ opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive,
opt_force_interactive, opt_trust_server_cert,
- opt_trust_server_cert_unknown_ca, opt_trust_server_cert_cn_mismatch,
- opt_trust_server_cert_expired, opt_trust_server_cert_not_yet_valid,
- opt_trust_server_cert_other_failure,
+ opt_trust_server_cert_failures,
opt_config_dir, opt_config_options, 0
};
@@ -1457,8 +1445,13 @@ const svn_opt_subcommand_desc2_t svn_cl_
" directory:\n"
" svn:ignore - A list of file glob patterns to ignore, one per line.\n"
" svn:global-ignores - Like svn:ignore, but inheritable.\n"
- " svn:auto-props - A list of file glob patterns and properties to set\n"
- " when adding such files; like [auto-props] in the client configuration.\n"
+ " svn:auto-props - Automatically set properties on files when they are\n"
+ " added or imported. Contains key-value pairs, one per line, in the format:\n"
+ " PATTERN = PROPNAME=VALUE[;PROPNAME=VALUE ...]\n"
+ " Example (where a literal ';' is escaped by adding another ';'):\n"
+ " *.html = svn:eol-style=native;svn:mime-type=text/html;; charset=UTF8\n"
+ " Applies recursively to all files added or imported under the directory\n"
+ " it is set on. See also [auto-props] in the client configuration file.\n"
" svn:externals - A list of module specifiers, one per line, in the\n"
" following format similar to the syntax of 'svn checkout':\n"
" [-r REV] URL[@PEG] LOCALPATH\n"
@@ -2187,20 +2180,17 @@ sub_main(int *exit_code, int argc, const
force_interactive = TRUE;
break;
case opt_trust_server_cert: /* backwards compat to 1.8 */
- case opt_trust_server_cert_unknown_ca:
opt_state.trust_server_cert_unknown_ca = TRUE;
break;
- case opt_trust_server_cert_cn_mismatch:
- opt_state.trust_server_cert_cn_mismatch = TRUE;
- break;
- case opt_trust_server_cert_expired:
- opt_state.trust_server_cert_expired = TRUE;
- break;
- case opt_trust_server_cert_not_yet_valid:
- opt_state.trust_server_cert_not_yet_valid = TRUE;
- break;
- case opt_trust_server_cert_other_failure:
- opt_state.trust_server_cert_other_failure = TRUE;
+ case opt_trust_server_cert_failures:
+ SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ SVN_ERR(svn_cmdline__parse_trust_options(
+ &opt_state.trust_server_cert_unknown_ca,
+ &opt_state.trust_server_cert_cn_mismatch,
+ &opt_state.trust_server_cert_expired,
+ &opt_state.trust_server_cert_not_yet_valid,
+ &opt_state.trust_server_cert_other_failure,
+ utf8_opt_arg, pool));
break;
case opt_no_diff_added:
opt_state.diff.no_diff_added = TRUE;
@@ -2637,25 +2627,13 @@ sub_main(int *exit_code, int argc, const
/* --trust-* options can only be used with --non-interactive */
if (!opt_state.non_interactive)
{
- if (opt_state.trust_server_cert_unknown_ca)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-unknown-ca requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_cn_mismatch)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-cn-mismatch requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_expired)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-expired requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_not_yet_valid)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-not-yet-valid requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_other_failure)
+ if (opt_state.trust_server_cert_unknown_ca
+ || opt_state.trust_server_cert_cn_mismatch
+ || opt_state.trust_server_cert_expired
+ || opt_state.trust_server_cert_not_yet_valid
+ || opt_state.trust_server_cert_other_failure)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-other-failure requires "
+ _("--trust-server-cert-failures requires "
"--non-interactive"));
}
Modified: subversion/branches/move-tracking-2/subversion/svnbench/svnbench.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnbench/svnbench.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnbench/svnbench.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnbench/svnbench.c Tue May 26 08:57:33 2015
@@ -67,11 +67,7 @@ typedef enum svn_cl__longopt_t {
opt_with_all_revprops,
opt_with_no_revprops,
opt_trust_server_cert,
- opt_trust_server_cert_unknown_ca,
- opt_trust_server_cert_cn_mismatch,
- opt_trust_server_cert_expired,
- opt_trust_server_cert_not_yet_valid,
- opt_trust_server_cert_other_failure,
+ opt_trust_server_cert_failures,
opt_changelist
} svn_cl__longopt_t;
@@ -127,29 +123,23 @@ const apr_getopt_option_t svn_cl__option
{"no-auth-cache", opt_no_auth_cache, 0,
N_("do not cache authentication tokens")},
{"trust-server-cert", opt_trust_server_cert, 0,
- N_("deprecated; same as --trust-unknown-ca")},
- {"trust-unknown-ca", opt_trust_server_cert_unknown_ca, 0,
- N_("with --non-interactive, accept SSL server\n"
+ N_("deprecated; same as\n"
" "
- "certificates from unknown certificate authorities")},
- {"trust-cn-mismatch", opt_trust_server_cert_cn_mismatch, 0,
+ "--trust-server-cert-failures=unknown-ca")},
+ {"trust-server-cert-failures", opt_trust_server_cert_failures, 1,
N_("with --non-interactive, accept SSL server\n"
" "
- "certificates even if the server hostname does not\n"
+ "certificates with failures; ARG is comma-separated\n"
" "
- "match the certificate's common name attribute")},
- {"trust-expired", opt_trust_server_cert_expired, 0,
- N_("with --non-interactive, accept expired SSL server\n"
+ "list of 'unknown-ca' (Unknown Authority),\n"
" "
- "certificates")},
- {"trust-not-yet-valid", opt_trust_server_cert_not_yet_valid, 0,
- N_("with --non-interactive, accept SSL server\n"
+ "'cn-mismatch' (Hostname mismatch), 'expired'\n"
" "
- "certificates from the future")},
- {"trust-other-failure", opt_trust_server_cert_other_failure, 0,
- N_("with --non-interactive, accept SSL server\n"
+ "(Expired certificate), 'not-yet-valid' (Not yet\n"
+ " "
+ "valid certificate) and 'other' (all other not\n"
" "
- "certificates with failures other than the above")},
+ "separately classified certificate errors).")},
{"non-interactive", opt_non_interactive, 0,
N_("do no interactive prompting")},
{"config-dir", opt_config_dir, 1,
@@ -205,9 +195,7 @@ const apr_getopt_option_t svn_cl__option
willy-nilly to every invocation of 'svn') . */
const int svn_cl__global_options[] =
{ opt_auth_username, opt_auth_password, opt_no_auth_cache, opt_non_interactive,
- opt_trust_server_cert, opt_trust_server_cert_unknown_ca,
- opt_trust_server_cert_cn_mismatch, opt_trust_server_cert_expired,
- opt_trust_server_cert_not_yet_valid, opt_trust_server_cert_other_failure,
+ opt_trust_server_cert, opt_trust_server_cert_failures,
opt_config_dir, opt_config_options, 0
};
@@ -624,20 +612,17 @@ sub_main(int *exit_code, int argc, const
opt_state.non_interactive = TRUE;
break;
case opt_trust_server_cert: /* backwards compat to 1.8 */
- case opt_trust_server_cert_unknown_ca:
opt_state.trust_server_cert_unknown_ca = TRUE;
break;
- case opt_trust_server_cert_cn_mismatch:
- opt_state.trust_server_cert_cn_mismatch = TRUE;
- break;
- case opt_trust_server_cert_expired:
- opt_state.trust_server_cert_expired = TRUE;
- break;
- case opt_trust_server_cert_not_yet_valid:
- opt_state.trust_server_cert_not_yet_valid = TRUE;
- break;
- case opt_trust_server_cert_other_failure:
- opt_state.trust_server_cert_other_failure = TRUE;
+ case opt_trust_server_cert_failures:
+ SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+ SVN_ERR(svn_cmdline__parse_trust_options(
+ &opt_state.trust_server_cert_unknown_ca,
+ &opt_state.trust_server_cert_cn_mismatch,
+ &opt_state.trust_server_cert_expired,
+ &opt_state.trust_server_cert_not_yet_valid,
+ &opt_state.trust_server_cert_other_failure,
+ utf8_opt_arg, pool));
break;
case opt_config_dir:
{
@@ -813,25 +798,13 @@ sub_main(int *exit_code, int argc, const
/* --trust-* options can only be used with --non-interactive */
if (!opt_state.non_interactive)
{
- if (opt_state.trust_server_cert_unknown_ca)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-unknown-ca requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_cn_mismatch)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-cn-mismatch requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_expired)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-expired requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_not_yet_valid)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-not-yet-valid requires "
- "--non-interactive"));
- if (opt_state.trust_server_cert_other_failure)
+ if (opt_state.trust_server_cert_unknown_ca
+ || opt_state.trust_server_cert_cn_mismatch
+ || opt_state.trust_server_cert_expired
+ || opt_state.trust_server_cert_not_yet_valid
+ || opt_state.trust_server_cert_other_failure)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-other-failure requires "
+ _("--trust-server-cert-failures requires "
"--non-interactive"));
}
Modified: subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c?rev=1681721&r1=1681720&r2=1681721&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmucc/svnmucc.c Tue May 26 08:57:33 2015
@@ -295,18 +295,16 @@ help(FILE *stream, apr_pool_t *pool)
" prompt only if standard input is a terminal)\n"
" --force-interactive : do interactive prompting even if standard\n"
" input is not a terminal\n"
- " --trust-server-cert : deprecated; same as --trust-unknown-ca\n"
- " --trust-unknown-ca : with --non-interactive, accept SSL server\n"
- " certificates from unknown certificate authorities\n"
- " --trust-cn-mismatch : with --non-interactive, accept SSL server\n"
- " certificates even if the server hostname does not\n"
- " match the certificate's common name attribute\n"
- " --trust-expired : with --non-interactive, accept expired SSL server\n"
- " certificates\n"
- " --trust-not-yet-valid : with --non-interactive, accept SSL server\n"
- " certificates from the future\n"
- " --trust-other-failure : with --non-interactive, accept SSL server\n"
- " certificates with failures other than the above\n"
+ " --trust-server-cert : deprecated;\n"
+ " same as --trust-server-cert-failures=unknown-ca\n"
+ " --trust-server-cert-failures ARG\n"
+ " with --non-interactive, accept SSL server\n"
+ " certificates with failures; ARG is comma-separated\n"
+ " list of 'unknown-ca' (Unknown Authority),\n"
+ " 'cn-mismatch' (Hostname mismatch), 'expired'\n"
+ " (Expired certificate),'not-yet-valid' (Not yet\n"
+ " valid certificate) and 'other' (all other not\n"
+ " separately classified certificate errors).\n"
" -X [--extra-args] ARG : append arguments from file ARG (one per line;\n"
" use \"-\" to read from standard input)\n"
" --config-dir ARG : use ARG to override the config directory\n"
@@ -472,11 +470,7 @@ sub_main(int *exit_code, int argc, const
non_interactive_opt,
force_interactive_opt,
trust_server_cert_opt,
- trust_server_cert_unknown_ca_opt,
- trust_server_cert_cn_mismatch_opt,
- trust_server_cert_expired_opt,
- trust_server_cert_not_yet_valid_opt,
- trust_server_cert_other_failure_opt,
+ trust_server_cert_failures_opt,
};
static const apr_getopt_option_t options[] = {
{"message", 'm', 1, ""},
@@ -492,11 +486,7 @@ sub_main(int *exit_code, int argc, const
{"non-interactive", non_interactive_opt, 0, ""},
{"force-interactive", force_interactive_opt, 0, ""},
{"trust-server-cert", trust_server_cert_opt, 0, ""},
- {"trust-unknown-ca", trust_server_cert_unknown_ca_opt, 0, ""},
- {"trust-cn-mismatch", trust_server_cert_cn_mismatch_opt, 0, ""},
- {"trust-expired", trust_server_cert_expired_opt, 0, ""},
- {"trust-not-yet-valid", trust_server_cert_not_yet_valid_opt, 0, ""},
- {"trust-other-failure", trust_server_cert_other_failure_opt, 0, ""},
+ {"trust-server-cert-failures", trust_server_cert_failures_opt, 1, ""},
{"config-dir", config_dir_opt, 1, ""},
{"config-option", config_inline_opt, 1, ""},
{"no-auth-cache", no_auth_cache_opt, 0, ""},
@@ -604,20 +594,17 @@ sub_main(int *exit_code, int argc, const
force_interactive = TRUE;
break;
case trust_server_cert_opt: /* backward compat */
- case trust_server_cert_unknown_ca_opt:
trust_unknown_ca = TRUE;
break;
- case trust_server_cert_cn_mismatch_opt:
- trust_cn_mismatch = TRUE;
- break;
- case trust_server_cert_expired_opt:
- trust_expired = TRUE;
- break;
- case trust_server_cert_not_yet_valid_opt:
- trust_not_yet_valid = TRUE;
- break;
- case trust_server_cert_other_failure_opt:
- trust_other_failure = TRUE;
+ case trust_server_cert_failures_opt:
+ SVN_ERR(svn_utf_cstring_to_utf8(&opt_arg, arg, pool));
+ SVN_ERR(svn_cmdline__parse_trust_options(
+ &trust_unknown_ca,
+ &trust_cn_mismatch,
+ &trust_expired,
+ &trust_not_yet_valid,
+ &trust_other_failure,
+ opt_arg, pool));
break;
case config_dir_opt:
SVN_ERR(svn_utf_cstring_to_utf8(&config_dir, arg, pool));
@@ -665,25 +652,10 @@ sub_main(int *exit_code, int argc, const
if (!non_interactive)
{
- if (trust_unknown_ca)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-unknown-ca requires "
- "--non-interactive"));
- if (trust_cn_mismatch)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-cn-mismatch requires "
- "--non-interactive"));
- if (trust_expired)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-expired requires "
- "--non-interactive"));
- if (trust_not_yet_valid)
- return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-not-yet-valid requires "
- "--non-interactive"));
- if (trust_other_failure)
+ if (trust_unknown_ca || trust_cn_mismatch || trust_expired
+ || trust_not_yet_valid || trust_other_failure)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("--trust-other-failure requires "
+ _("--trust-server-cert-failures requires "
"--non-interactive"));
}