You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2010/12/02 21:55:18 UTC
svn commit: r1041580 [8/35] - in
/subversion/branches/gpg-agent-password-store: ./ build/ build/ac-macros/
build/generator/ build/generator/templates/ build/win32/
contrib/hook-scripts/ contrib/server-side/ notes/http-and-webdav/
notes/wc-ng/ subversio...
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/options.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/options.c Thu Dec 2 20:55:08 2010
@@ -566,12 +566,15 @@ svn_ra_serf__has_capability(svn_ra_sessi
support mergeinfo. */
svn_mergeinfo_catalog_t ignored;
svn_error_t *err;
+ svn_boolean_t validate_inherited_mergeinfo = FALSE;
apr_array_header_t *paths = apr_array_make(pool, 1,
sizeof(char *));
APR_ARRAY_PUSH(paths, const char *) = "";
err = svn_ra_serf__get_mergeinfo(ra_session, &ignored, paths, 0,
- FALSE, FALSE, pool);
+ FALSE,
+ &validate_inherited_mergeinfo,
+ FALSE, pool);
if (err)
{
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/ra_serf.h?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_serf/ra_serf.h Thu Dec 2 20:55:08 2010
@@ -1379,13 +1379,15 @@ svn_ra_serf__get_locks(svn_ra_session_t
svn_depth_t depth,
apr_pool_t *pool);
-svn_error_t * svn_ra_serf__get_mergeinfo(svn_ra_session_t *ra_session,
- apr_hash_t **mergeinfo,
- const apr_array_header_t *paths,
- svn_revnum_t revision,
- svn_mergeinfo_inheritance_t inherit,
- svn_boolean_t include_descendants,
- apr_pool_t *pool);
+svn_error_t * svn_ra_serf__get_mergeinfo(
+ svn_ra_session_t *ra_session,
+ apr_hash_t **mergeinfo,
+ const apr_array_header_t *paths,
+ svn_revnum_t revision,
+ svn_mergeinfo_inheritance_t inherit,
+ svn_boolean_t *validate_inherited_mergeinfo,
+ svn_boolean_t include_descendants,
+ apr_pool_t *pool);
/* Exchange capabilities with the server, by sending an OPTIONS
* request announcing the client's capabilities, and by filling
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/client.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/client.c Thu Dec 2 20:55:08 2010
@@ -1153,15 +1153,34 @@ static svn_error_t *ra_svn_get_dir(svn_r
return SVN_NO_ERROR;
}
+/* Converts a apr_uint64_t with values TRUE, FALSE or
+ SVN_RA_SVN_UNSPECIFIED_NUMBER as provided by svn_ra_svn_parse_tuple
+ to a svn_tristate_t */
+static svn_tristate_t
+optbool_to_tristate(apr_uint64_t v)
+{
+ switch (v)
+ {
+ case TRUE:
+ return svn_tristate_true;
+ case FALSE:
+ return svn_tristate_false;
+ default: /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
+ return svn_tristate_unknown;
+ }
+}
+
/* If REVISION is SVN_INVALID_REVNUM, no value is sent to the
server, which defaults to youngest. */
-static svn_error_t *ra_svn_get_mergeinfo(svn_ra_session_t *session,
- svn_mergeinfo_catalog_t *catalog,
- const apr_array_header_t *paths,
- svn_revnum_t revision,
- svn_mergeinfo_inheritance_t inherit,
- svn_boolean_t include_descendants,
- apr_pool_t *pool)
+static svn_error_t *ra_svn_get_mergeinfo(
+ svn_ra_session_t *session,
+ svn_mergeinfo_catalog_t *catalog,
+ const apr_array_header_t *paths,
+ svn_revnum_t revision,
+ svn_mergeinfo_inheritance_t inherit,
+ svn_boolean_t *validate_inherited_mergeinfo,
+ svn_boolean_t include_descendants,
+ apr_pool_t *pool)
{
svn_ra_svn__session_baton_t *sess_baton = session->priv;
svn_ra_svn_conn_t *conn = sess_baton->conn;
@@ -1169,6 +1188,7 @@ static svn_error_t *ra_svn_get_mergeinfo
apr_array_header_t *mergeinfo_tuple;
svn_ra_svn_item_t *elt;
const char *path;
+ apr_uint64_t validated_inherited_mergeinfo;
SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((!", "get-mergeinfo"));
for (i = 0; i < paths->nelts; i++)
@@ -1176,12 +1196,17 @@ static svn_error_t *ra_svn_get_mergeinfo
path = APR_ARRAY_IDX(paths, i, const char *);
SVN_ERR(svn_ra_svn_write_cstring(conn, pool, path));
}
- SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)(?r)wb)", revision,
+ SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)(?r)wbb)", revision,
svn_inheritance_to_word(inherit),
- include_descendants));
+ include_descendants,
+ *validate_inherited_mergeinfo));
SVN_ERR(handle_auth_request(sess_baton, pool));
- SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "l", &mergeinfo_tuple));
+ SVN_ERR(svn_ra_svn_read_cmd_response(conn, pool, "l?B", &mergeinfo_tuple,
+ &validated_inherited_mergeinfo));
+
+ *validate_inherited_mergeinfo =
+ (optbool_to_tristate(validated_inherited_mergeinfo) == svn_tristate_true);
*catalog = NULL;
if (mergeinfo_tuple->nelts > 0)
@@ -1313,22 +1338,6 @@ static svn_error_t *ra_svn_diff(svn_ra_s
return SVN_NO_ERROR;
}
-/* Converts a apr_uint64_t with values TRUE, FALSE or
- SVN_RA_SVN_UNSPECIFIED_NUMBER as provided by svn_ra_svn_parse_tuple
- to a svn_tristate_t */
-static svn_tristate_t
-optbool_to_tristate(apr_uint64_t v)
-{
- switch (v)
- {
- case TRUE:
- return svn_tristate_true;
- case FALSE:
- return svn_tristate_false;
- default: /* Contains SVN_RA_SVN_UNSPECIFIED_NUMBER */
- return svn_tristate_unknown;
- }
-}
static svn_error_t *ra_svn_log(svn_ra_session_t *session,
const apr_array_header_t *paths,
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/marshal.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_ra_svn/marshal.c Thu Dec 2 20:55:08 2010
@@ -44,6 +44,12 @@
#define svn_iswhitespace(c) ((c) == ' ' || (c) == '\n')
+/* If we receive data that *claims* to be followed by a very long string,
+ * we should not trust that claim right away. But everything up to 1 MB
+ * should be too small to be instrumental for a DOS attack. */
+
+#define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
+
/* --- CONNECTION INITIALIZATION --- */
svn_ra_svn_conn_t *svn_ra_svn_create_conn(apr_socket_t *sock,
@@ -296,8 +302,8 @@ static svn_error_t *readbuf_fill(svn_ra_
return SVN_NO_ERROR;
}
-static svn_error_t *readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- char *result)
+static APR_INLINE svn_error_t *
+readbuf_getchar(svn_ra_svn_conn_t *conn, apr_pool_t *pool, char *result)
{
if (conn->read_ptr == conn->read_end)
SVN_ERR(readbuf_fill(conn, pool));
@@ -537,15 +543,14 @@ svn_error_t *svn_ra_svn_write_tuple(svn_
/* --- READING DATA ITEMS --- */
-/* Read LEN bytes from CONN into already-allocated structure ITEM.
- * Afterwards, *ITEM is of type 'SVN_RA_SVN_STRING', and its string
- * data is allocated in POOL. */
-static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- svn_ra_svn_item_t *item, apr_uint64_t len)
+/* Read LEN bytes from CONN into a supposedly empty STRINGBUF.
+ * POOL will be used for temporary allocations. */
+static svn_error_t *
+read_long_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+ svn_stringbuf_t *stringbuf, apr_uint64_t len)
{
char readbuf[4096];
apr_size_t readbuf_len;
- svn_stringbuf_t *stringbuf = svn_stringbuf_create("", pool);
/* We can't store strings longer than the maximum size of apr_size_t,
* so check for wrapping */
@@ -565,6 +570,57 @@ static svn_error_t *read_string(svn_ra_s
len -= readbuf_len;
}
+ return SVN_NO_ERROR;
+}
+
+/* Read LEN bytes from CONN into already-allocated structure ITEM.
+ * Afterwards, *ITEM is of type 'SVN_RA_SVN_STRING', and its string
+ * data is allocated in POOL. */
+static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+ svn_ra_svn_item_t *item, apr_uint64_t len)
+{
+ svn_stringbuf_t *stringbuf;
+
+ /* We should not use large strings in our protocol. However, we may
+ * receive a claim that a very long string is going to follow. In that
+ * case, we start small and wait for all that data to actually show up.
+ * This does not fully prevent DOS attacs but makes them harder (you
+ * have to actually send gigabytes of data).
+ */
+ if (len > SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD)
+ {
+ /* This string might take a large amount of memory. Don't allocate
+ * the whole buffer at once, so to prevent OOM issues by corrupted
+ * network data.
+ */
+ stringbuf = svn_stringbuf_create("", pool);
+ SVN_ERR(read_long_string(conn, pool, stringbuf, len));
+ }
+ else
+ {
+ /* This is a reasonably sized string. So, provide a buffer large
+ * enough to prevent re-allocation as long as the data transmission
+ * is not flawed.
+ */
+ stringbuf = svn_stringbuf_create_ensure(len, pool);
+
+ /* Read the string data directly into the string structure.
+ * Do it iteratively, if necessary.
+ */
+ while (len)
+ {
+ apr_size_t readbuf_len = (apr_size_t)len;
+ char *dest = stringbuf->data + stringbuf->len;
+ SVN_ERR(readbuf_read(conn, pool, dest, readbuf_len));
+
+ stringbuf->len += readbuf_len;
+ stringbuf->data[stringbuf->len] = '\0';
+ len -= readbuf_len;
+ }
+ }
+
+ /* Return the string properly wrapped into an RA_SVN item.
+ */
item->kind = SVN_RA_SVN_STRING;
item->u.string = apr_palloc(pool, sizeof(*item->u.string));
item->u.string->data = stringbuf->data;
@@ -625,7 +681,8 @@ static svn_error_t *read_item(svn_ra_svn
else if (svn_ctype_isalpha(c))
{
/* It's a word. */
- str = svn_stringbuf_ncreate(&c, 1, pool);
+ str = svn_stringbuf_create_ensure(16, pool);
+ svn_stringbuf_appendbyte(str, c);
while (1)
{
SVN_ERR(readbuf_getchar(conn, pool, &c));
@@ -640,7 +697,7 @@ static svn_error_t *read_item(svn_ra_svn
{
/* Read in the list items. */
item->kind = SVN_RA_SVN_LIST;
- item->u.list = apr_array_make(pool, 0, sizeof(svn_ra_svn_item_t));
+ item->u.list = apr_array_make(pool, 4, sizeof(svn_ra_svn_item_t));
while (1)
{
SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/dump.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/dump.c Thu Dec 2 20:55:08 2010
@@ -386,7 +386,7 @@ dump_node(struct edit_baton *eb,
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
compare_root, compare_path,
- TRUE, pool));
+ FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -395,7 +395,7 @@ dump_node(struct edit_baton *eb,
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
compare_root, compare_path,
- TRUE, pool));
+ FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -513,7 +513,7 @@ dump_node(struct edit_baton *eb,
{
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
compare_root, compare_path,
- TRUE, pool));
+ FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -522,7 +522,7 @@ dump_node(struct edit_baton *eb,
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
compare_root, compare_path,
- TRUE, pool));
+ FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -542,7 +542,7 @@ dump_node(struct edit_baton *eb,
": %" SVN_FILESIZE_T_FMT "\n", textlen));
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
- eb->fs_root, path, TRUE, pool));
+ eb->fs_root, path, FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
@@ -550,7 +550,7 @@ dump_node(struct edit_baton *eb,
": %s\n", hex_digest));
SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_sha1,
- eb->fs_root, path, TRUE, pool));
+ eb->fs_root, path, FALSE, pool));
hex_digest = svn_checksum_to_cstring(checksum, pool);
if (hex_digest)
SVN_ERR(svn_stream_printf(eb->stream, pool,
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/fs-wrap.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/fs-wrap.c Thu Dec 2 20:55:08 2010
@@ -597,15 +597,16 @@ svn_repos_fs_get_locks2(apr_hash_t **loc
svn_error_t *
-svn_repos_fs_get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo,
- svn_repos_t *repos,
- const apr_array_header_t *paths,
- svn_revnum_t rev,
- svn_mergeinfo_inheritance_t inherit,
- svn_boolean_t include_descendants,
- svn_repos_authz_func_t authz_read_func,
- void *authz_read_baton,
- apr_pool_t *pool)
+svn_repos_fs_get_mergeinfo2(svn_mergeinfo_catalog_t *mergeinfo,
+ svn_repos_t *repos,
+ const apr_array_header_t *paths,
+ svn_revnum_t rev,
+ svn_mergeinfo_inheritance_t inherit,
+ svn_boolean_t validate_inherited_mergeinfo,
+ svn_boolean_t include_descendants,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *pool)
{
/* Here we cast away 'const', but won't try to write through this pointer
* without first allocating a new array. */
@@ -653,8 +654,9 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
the change itself. */
/* ### TODO(reint): ... but how about descendant merged-to paths? */
if (readable_paths->nelts > 0)
- SVN_ERR(svn_fs_get_mergeinfo(mergeinfo, root, readable_paths, inherit,
- include_descendants, pool));
+ SVN_ERR(svn_fs_get_mergeinfo2(mergeinfo, root, readable_paths, inherit,
+ validate_inherited_mergeinfo,
+ include_descendants, pool));
else
*mergeinfo = apr_hash_make(pool);
@@ -662,6 +664,26 @@ svn_repos_fs_get_mergeinfo(svn_mergeinfo
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_repos_fs_get_mergeinfo(svn_mergeinfo_catalog_t *mergeinfo,
+ svn_repos_t *repos,
+ const apr_array_header_t *paths,
+ svn_revnum_t rev,
+ svn_mergeinfo_inheritance_t inherit,
+ svn_boolean_t include_descendants,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ apr_pool_t *pool)
+{
+ return svn_error_return(svn_repos_fs_get_mergeinfo2(mergeinfo, repos,
+ paths, rev, inherit,
+ FALSE,
+ include_descendants,
+ authz_read_func,
+ authz_read_baton,
+ pool));
+}
+
struct pack_notify_baton
{
svn_repos_notify_func_t notify_func;
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/load.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/load.c Thu Dec 2 20:55:08 2010
@@ -43,73 +43,6 @@
/*----------------------------------------------------------------------*/
-/** Batons used herein **/
-
-struct parse_baton
-{
- svn_repos_t *repos;
- svn_fs_t *fs;
-
- svn_boolean_t use_history;
- svn_boolean_t use_pre_commit_hook;
- svn_boolean_t use_post_commit_hook;
- enum svn_repos_load_uuid uuid_action;
- const char *parent_dir;
- svn_repos_notify_func_t notify_func;
- void *notify_baton;
- svn_repos_notify_t *notify;
- apr_pool_t *pool;
-
- /* A hash mapping copy-from revisions and mergeinfo range revisions
- (svn_revnum_t *) in the dump stream to their corresponding revisions
- (svn_revnum_t *) in the loaded repository. The hash and its
- contents are allocated in POOL. */
- apr_hash_t *rev_map;
-
- /* The most recent (youngest) revision from the dump stream mapped in
- REV_MAP. If no revisions have been mapped yet, this is set to
- SVN_INVALID_REVNUM. */
- svn_revnum_t last_rev_mapped;
-
- /* The oldest old revision loaded from the dump stream. If no revisions
- have been loaded yet, this is set to SVN_INVALID_REVNUM. */
- svn_revnum_t oldest_old_rev;
-};
-
-struct revision_baton
-{
- svn_revnum_t rev;
-
- svn_fs_txn_t *txn;
- svn_fs_root_t *txn_root;
-
- const svn_string_t *datestamp;
-
- apr_int32_t rev_offset;
-
- struct parse_baton *pb;
- apr_pool_t *pool;
-};
-
-struct node_baton
-{
- const char *path;
- svn_node_kind_t kind;
- enum svn_node_action action;
- svn_checksum_t *base_checksum; /* null, if not available */
- svn_checksum_t *result_checksum; /* null, if not available */
- svn_checksum_t *copy_source_checksum; /* null, if not available */
-
- svn_revnum_t copyfrom_rev;
- const char *copyfrom_path;
-
- struct revision_baton *rb;
- apr_pool_t *pool;
-};
-
-
-/*----------------------------------------------------------------------*/
-
/** The parser and related helper funcs **/
@@ -236,170 +169,6 @@ read_key_or_val(char **pbuf,
}
-/* Prepend the mergeinfo source paths in MERGEINFO_ORIG with PARENT_DIR, and
- return it in *MERGEINFO_VAL. */
-static svn_error_t *
-prefix_mergeinfo_paths(svn_string_t **mergeinfo_val,
- const svn_string_t *mergeinfo_orig,
- const char *parent_dir,
- apr_pool_t *pool)
-{
- apr_hash_t *prefixed_mergeinfo, *mergeinfo;
- apr_hash_index_t *hi;
- void *rangelist;
-
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo, mergeinfo_orig->data, pool));
- prefixed_mergeinfo = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, mergeinfo); hi; hi = apr_hash_next(hi))
- {
- const void *key;
- const char *path, *merge_source;
-
- apr_hash_this(hi, &key, NULL, &rangelist);
- merge_source = key;
-
- /* The svn:mergeinfo property syntax demands absolute repository
- paths, so prepend a leading slash if PARENT_DIR lacks one. */
- if (*parent_dir != '/')
- path = svn_path_join_many(pool, "/", parent_dir,
- merge_source + 1, NULL);
- else
- path = svn_path_join(parent_dir, merge_source + 1, pool);
-
- apr_hash_set(prefixed_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);
- }
- return svn_mergeinfo_to_string(mergeinfo_val, prefixed_mergeinfo, pool);
-}
-
-
-/* Examine the mergeinfo in INITIAL_VAL, renumber revisions in rangelists
- as appropriate, and return the (possibly new) mergeinfo in *FINAL_VAL
- (allocated from POOL). */
-static svn_error_t *
-renumber_mergeinfo_revs(svn_string_t **final_val,
- const svn_string_t *initial_val,
- struct revision_baton *rb,
- apr_pool_t *pool)
-{
- apr_pool_t *subpool = svn_pool_create(pool);
- svn_mergeinfo_t mergeinfo, predates_stream_mergeinfo;
- svn_mergeinfo_t final_mergeinfo = apr_hash_make(subpool);
- apr_hash_index_t *hi;
-
- SVN_ERR(svn_mergeinfo_parse(&mergeinfo, initial_val->data, subpool));
-
- /* Issue #3020
- http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16
- Remove mergeinfo older than the oldest revision in the dump stream
- and adjust its revisions by the difference between the head rev of
- the target repository and the current dump stream rev. */
- if (rb->pb->oldest_old_rev > 1)
- {
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
- &predates_stream_mergeinfo, mergeinfo,
- rb->pb->oldest_old_rev - 1, 0,
- TRUE, subpool, subpool));
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
- &mergeinfo, mergeinfo,
- rb->pb->oldest_old_rev - 1, 0,
- FALSE, subpool, subpool));
- SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists(
- &predates_stream_mergeinfo, predates_stream_mergeinfo,
- -rb->rev_offset, subpool, subpool));
- }
- else
- {
- predates_stream_mergeinfo = NULL;
- }
-
- for (hi = apr_hash_first(subpool, mergeinfo); hi; hi = apr_hash_next(hi))
- {
- const char *merge_source;
- apr_array_header_t *rangelist;
- struct parse_baton *pb = rb->pb;
- int i;
- const void *key;
- void *val;
-
- apr_hash_this(hi, &key, NULL, &val);
- merge_source = key;
- rangelist = val;
-
- /* Possibly renumber revisions in merge source's rangelist. */
- for (i = 0; i < rangelist->nelts; i++)
- {
- svn_revnum_t *rev_from_map;
- svn_merge_range_t *range = APR_ARRAY_IDX(rangelist, i,
- svn_merge_range_t *);
- rev_from_map = apr_hash_get(pb->rev_map, &range->start,
- sizeof(svn_revnum_t));
- if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
- {
- range->start = *rev_from_map;
- }
- else if (range->start == pb->oldest_old_rev - 1)
- {
- /* Since the start revision of svn_merge_range_t are not
- inclusive there is one possible valid start revision that
- won't be found in the PB->REV_MAP mapping of load stream
- revsions to loaded revisions: The revision immediately
- preceeding the oldest revision from the load stream.
- This is a valid revision for mergeinfo, but not a valid
- copy from revision (which PB->REV_MAP also maps for) so it
- will never be in the mapping.
-
- If that is what we have here, then find the mapping for the
- oldest rev from the load stream and subtract 1 to get the
- renumbered, non-inclusive, start revision. */
- rev_from_map = apr_hash_get(pb->rev_map, &pb->oldest_old_rev,
- sizeof(svn_revnum_t));
- if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
- range->start = *rev_from_map - 1;
- }
- else
- {
- /* If we can't remap the start revision then don't even bother
- trying to remap the end revision. It's possible we might
- actually succeed at the latter, which can result in invalid
- mergeinfo with a start rev > end rev. If that gets into the
- repository then a world of bustage breaks loose anytime that
- bogus mergeinfo is parsed. See
- http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
- */
- continue;
- }
-
- rev_from_map = apr_hash_get(pb->rev_map, &range->end,
- sizeof(svn_revnum_t));
- if (rev_from_map && SVN_IS_VALID_REVNUM(*rev_from_map))
- range->end = *rev_from_map;
- }
- apr_hash_set(final_mergeinfo, merge_source,
- APR_HASH_KEY_STRING, rangelist);
- }
-
- if (predates_stream_mergeinfo)
- SVN_ERR(svn_mergeinfo_merge(final_mergeinfo, predates_stream_mergeinfo,
- subpool));
-
- SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool));
-
- /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0
- or r1. However, svndumpfilter can be abused to produce r1 merge source
- revs. So if we encounter any, then strip them out, no need to put them
- into the load target. */
- SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo,
- final_mergeinfo,
- 1, 0, FALSE,
- subpool, subpool));
-
- SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool));
- svn_pool_destroy(subpool);
-
- return SVN_NO_ERROR;
-}
-
-
/* Read CONTENT_LENGTH bytes from STREAM, parsing the bytes as an
encoded Subversion properties hash, and making multiple calls to
PARSE_FNS->set_*_property on RECORD_BATON (depending on the value
@@ -480,38 +249,6 @@ parse_property_block(svn_stream_t *strea
/* Now, send the property pair to the vtable! */
if (is_node)
{
- /* svn_mergeinfo_parse() in parse_fns->set_node_property()
- will choke on mergeinfo with "\r\n" line endings, but we
- might legitimately encounter these in a dump stream. If
- so normalize the line endings to '\n' and make a
- notification to PARSE_BATON->FEEDBACK_STREAM that we
- have made this correction. */
- if (strcmp(keybuf, SVN_PROP_MERGEINFO) == 0
- && strstr(propstring.data, "\r"))
- {
- const char *prop_eol_normalized;
- struct parse_baton *pb = parse_baton;
-
- SVN_ERR(svn_subst_translate_cstring2(
- propstring.data,
- &prop_eol_normalized,
- "\n", /* translate to LF */
- FALSE, /* no repair */
- NULL, /* no keywords */
- FALSE, /* no expansion */
- proppool));
- propstring.data = prop_eol_normalized;
- propstring.len = strlen(prop_eol_normalized);
-
- if (pb->notify_func)
- {
- pb->notify->action =
- svn_repos_notify_load_normalized_mergeinfo;
- pb->notify_func(pb->notify_baton, pb->notify,
- proppool);
- }
- }
-
SVN_ERR(parse_fns->set_node_property(record_baton,
keybuf,
&propstring));
@@ -663,7 +400,10 @@ parse_format_version(const char *version
-/* The Main Parser Logic */
+/*----------------------------------------------------------------------*/
+
+/** The public routines **/
+
svn_error_t *
svn_repos_parse_dumpstream2(svn_stream_t *stream,
const svn_repos_parse_fns2_t *parse_fns,
@@ -952,662 +692,3 @@ svn_repos_parse_dumpstream2(svn_stream_t
svn_pool_destroy(nodepool);
return SVN_NO_ERROR;
}
-
-
-/*----------------------------------------------------------------------*/
-
-/** vtable for doing commits to a fs **/
-
-
-static struct node_baton *
-make_node_baton(apr_hash_t *headers,
- struct revision_baton *rb,
- apr_pool_t *pool)
-{
- struct node_baton *nb = apr_pcalloc(pool, sizeof(*nb));
- const char *val;
-
- /* Start with sensible defaults. */
- nb->rb = rb;
- nb->pool = pool;
- nb->kind = svn_node_unknown;
-
- /* Then add info from the headers. */
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_PATH,
- APR_HASH_KEY_STRING)))
- {
- if (rb->pb->parent_dir)
- nb->path = svn_path_join(rb->pb->parent_dir, val, pool);
- else
- nb->path = apr_pstrdup(pool, val);
- }
-
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_KIND,
- APR_HASH_KEY_STRING)))
- {
- if (! strcmp(val, "file"))
- nb->kind = svn_node_file;
- else if (! strcmp(val, "dir"))
- nb->kind = svn_node_dir;
- }
-
- nb->action = (enum svn_node_action)(-1); /* an invalid action code */
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_ACTION,
- APR_HASH_KEY_STRING)))
- {
- if (! strcmp(val, "change"))
- nb->action = svn_node_action_change;
- else if (! strcmp(val, "add"))
- nb->action = svn_node_action_add;
- else if (! strcmp(val, "delete"))
- nb->action = svn_node_action_delete;
- else if (! strcmp(val, "replace"))
- nb->action = svn_node_action_replace;
- }
-
- nb->copyfrom_rev = SVN_INVALID_REVNUM;
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV,
- APR_HASH_KEY_STRING)))
- {
- nb->copyfrom_rev = SVN_STR_TO_REV(val);
- }
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH,
- APR_HASH_KEY_STRING)))
- {
- if (rb->pb->parent_dir)
- nb->copyfrom_path = svn_path_join(rb->pb->parent_dir,
- (*val == '/' ? val + 1 : val), pool);
- else
- nb->copyfrom_path = apr_pstrdup(pool, val);
- }
-
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM,
- APR_HASH_KEY_STRING)))
- {
- svn_checksum_parse_hex(&nb->result_checksum, svn_checksum_md5, val, pool);
- }
-
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_CHECKSUM,
- APR_HASH_KEY_STRING)))
- {
- svn_checksum_parse_hex(&nb->base_checksum, svn_checksum_md5, val, pool);
- }
-
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM,
- APR_HASH_KEY_STRING)))
- {
- svn_checksum_parse_hex(&nb->copy_source_checksum, svn_checksum_md5, val,
- pool);
- }
-
- /* What's cool about this dump format is that the parser just
- ignores any unrecognized headers. :-) */
-
- return nb;
-}
-
-static struct revision_baton *
-make_revision_baton(apr_hash_t *headers,
- struct parse_baton *pb,
- apr_pool_t *pool)
-{
- struct revision_baton *rb = apr_pcalloc(pool, sizeof(*rb));
- const char *val;
-
- rb->pb = pb;
- rb->pool = pool;
- rb->rev = SVN_INVALID_REVNUM;
-
- if ((val = apr_hash_get(headers, SVN_REPOS_DUMPFILE_REVISION_NUMBER,
- APR_HASH_KEY_STRING)))
- rb->rev = SVN_STR_TO_REV(val);
-
- return rb;
-}
-
-
-static svn_error_t *
-new_revision_record(void **revision_baton,
- apr_hash_t *headers,
- void *parse_baton,
- apr_pool_t *pool)
-{
- struct parse_baton *pb = parse_baton;
- struct revision_baton *rb;
- svn_revnum_t head_rev;
-
- rb = make_revision_baton(headers, pb, pool);
- SVN_ERR(svn_fs_youngest_rev(&head_rev, pb->fs, pool));
-
- /* FIXME: This is a lame fallback loading multiple segments of dump in
- several separate operations. It is highly susceptible to race conditions.
- Calculate the revision 'offset' for finding copyfrom sources.
- It might be positive or negative. */
- rb->rev_offset = (apr_int32_t) (rb->rev) - (head_rev + 1);
-
- if (rb->rev > 0)
- {
- /* Create a new fs txn. */
- SVN_ERR(svn_fs_begin_txn2(&(rb->txn), pb->fs, head_rev, 0, pool));
- SVN_ERR(svn_fs_txn_root(&(rb->txn_root), rb->txn, pool));
-
- if (pb->notify_func)
- {
- pb->notify->action = svn_repos_notify_load_txn_start;
- pb->notify->old_revision = rb->rev;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
- }
-
- /* Stash the oldest "old" revision committed from the load stream. */
- if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev))
- pb->oldest_old_rev = rb->rev;
- }
-
- /* If we're parsing revision 0, only the revision are (possibly)
- interesting to us: when loading the stream into an empty
- filesystem, then we want new filesystem's revision 0 to have the
- same props. Otherwise, we just ignore revision 0 in the stream. */
-
- *revision_baton = rb;
- return SVN_NO_ERROR;
-}
-
-
-
-/* Factorized helper func for new_node_record() */
-static svn_error_t *
-maybe_add_with_history(struct node_baton *nb,
- struct revision_baton *rb,
- apr_pool_t *pool)
-{
- struct parse_baton *pb = rb->pb;
-
- if ((nb->copyfrom_path == NULL) || (! pb->use_history))
- {
- /* Add empty file or dir, without history. */
- if (nb->kind == svn_node_file)
- SVN_ERR(svn_fs_make_file(rb->txn_root, nb->path, pool));
-
- else if (nb->kind == svn_node_dir)
- SVN_ERR(svn_fs_make_dir(rb->txn_root, nb->path, pool));
- }
- else
- {
- /* Hunt down the source revision in this fs. */
- svn_fs_root_t *copy_root;
- svn_revnum_t src_rev = nb->copyfrom_rev - rb->rev_offset;
- svn_revnum_t *src_rev_from_map;
- if ((src_rev_from_map = apr_hash_get(pb->rev_map, &nb->copyfrom_rev,
- sizeof(nb->copyfrom_rev))))
- src_rev = *src_rev_from_map;
-
- if (! SVN_IS_VALID_REVNUM(src_rev))
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("Relative source revision %ld is not"
- " available in current repository"),
- src_rev);
-
- SVN_ERR(svn_fs_revision_root(©_root, pb->fs, src_rev, pool));
-
- if (nb->copy_source_checksum)
- {
- svn_checksum_t *checksum;
- SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5, copy_root,
- nb->copyfrom_path, TRUE, pool));
- if (!svn_checksum_match(nb->copy_source_checksum, checksum))
- return svn_error_createf
- (SVN_ERR_CHECKSUM_MISMATCH,
- NULL,
- apr_psprintf(pool, "%s:\n%s\n%s\n",
- _("Copy source checksum mismatch on copy from '%s'@%ld\n"
- "to '%s' in rev based on r%ld"),
- _(" expected: %s"),
- _(" actual: %s")),
- nb->copyfrom_path, src_rev,
- nb->path, rb->rev,
- svn_checksum_to_cstring_display(nb->copy_source_checksum, pool),
- svn_checksum_to_cstring_display(checksum, pool));
- }
-
- SVN_ERR(svn_fs_copy(copy_root, nb->copyfrom_path,
- rb->txn_root, nb->path, pool));
-
- if (pb->notify_func)
- {
- pb->notify->action = svn_repos_notify_load_copied_node;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
- }
- }
-
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-uuid_record(const char *uuid,
- void *parse_baton,
- apr_pool_t *pool)
-{
- struct parse_baton *pb = parse_baton;
- svn_revnum_t youngest_rev;
-
- if (pb->uuid_action == svn_repos_load_uuid_ignore)
- return SVN_NO_ERROR;
-
- if (pb->uuid_action != svn_repos_load_uuid_force)
- {
- SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, pool));
- if (youngest_rev != 0)
- return SVN_NO_ERROR;
- }
-
- return svn_fs_set_uuid(pb->fs, uuid, pool);
-}
-
-static svn_error_t *
-new_node_record(void **node_baton,
- apr_hash_t *headers,
- void *revision_baton,
- apr_pool_t *pool)
-{
- struct revision_baton *rb = revision_baton;
- struct parse_baton *pb = rb->pb;
- struct node_baton *nb;
-
- if (rb->rev == 0)
- return svn_error_create(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
- _("Malformed dumpstream: "
- "Revision 0 must not contain node records"));
-
- nb = make_node_baton(headers, rb, pool);
-
- /* Make sure we have an action we recognize. */
- if (nb->action < svn_node_action_change
- || nb->action > svn_node_action_replace)
- return svn_error_createf(SVN_ERR_STREAM_UNRECOGNIZED_DATA, NULL,
- _("Unrecognized node-action on node '%s'"),
- nb->path);
-
- if (pb->notify_func)
- {
- pb->notify->action = svn_repos_notify_load_node_start;
- pb->notify->node_action = nb->action;
- pb->notify->path = nb->path;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
- }
-
- switch (nb->action)
- {
- case svn_node_action_change:
- break;
-
- case svn_node_action_delete:
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
- break;
-
- case svn_node_action_add:
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
-
- case svn_node_action_replace:
- SVN_ERR(svn_fs_delete(rb->txn_root, nb->path, pool));
- SVN_ERR(maybe_add_with_history(nb, rb, pool));
- break;
- }
-
- *node_baton = nb;
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-set_revision_property(void *baton,
- const char *name,
- const svn_string_t *value)
-{
- struct revision_baton *rb = baton;
-
- if (rb->rev > 0)
- {
- SVN_ERR(svn_fs_change_txn_prop(rb->txn, name, value, rb->pool));
-
- /* Remember any datestamp that passes through! (See comment in
- close_revision() below.) */
- if (! strcmp(name, SVN_PROP_REVISION_DATE))
- rb->datestamp = svn_string_dup(value, rb->pool);
- }
- else if (rb->rev == 0)
- {
- /* Special case: set revision 0 properties when loading into an
- 'empty' filesystem. */
- struct parse_baton *pb = rb->pb;
- svn_revnum_t youngest_rev;
-
- SVN_ERR(svn_fs_youngest_rev(&youngest_rev, pb->fs, rb->pool));
-
- if (youngest_rev == 0)
- SVN_ERR(svn_fs_change_rev_prop2(pb->fs, 0, name, NULL, value,
- rb->pool));
- }
-
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-set_node_property(void *baton,
- const char *name,
- const svn_string_t *value)
-{
- struct node_baton *nb = baton;
- struct revision_baton *rb = nb->rb;
- const char *parent_dir = rb->pb->parent_dir;
-
- if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
- {
- /* Renumber mergeinfo as appropriate. */
- svn_string_t *renumbered_mergeinfo;
- SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, value, rb,
- nb->pool));
- value = renumbered_mergeinfo;
- if (parent_dir)
- {
- /* Prefix the merge source paths with PARENT_DIR. */
- /* ASSUMPTION: All source paths are included in the dump stream. */
- svn_string_t *mergeinfo_val;
- SVN_ERR(prefix_mergeinfo_paths(&mergeinfo_val, value, parent_dir,
- nb->pool));
- value = mergeinfo_val;
- }
- }
-
- return svn_fs_change_node_prop(rb->txn_root, nb->path,
- name, value, nb->pool);
-}
-
-
-static svn_error_t *
-delete_node_property(void *baton,
- const char *name)
-{
- struct node_baton *nb = baton;
- struct revision_baton *rb = nb->rb;
-
- return svn_fs_change_node_prop(rb->txn_root, nb->path,
- name, NULL, nb->pool);
-}
-
-
-static svn_error_t *
-remove_node_props(void *baton)
-{
- struct node_baton *nb = baton;
- struct revision_baton *rb = nb->rb;
- apr_hash_t *proplist;
- apr_hash_index_t *hi;
-
- SVN_ERR(svn_fs_node_proplist(&proplist,
- rb->txn_root, nb->path, nb->pool));
-
- for (hi = apr_hash_first(nb->pool, proplist); hi; hi = apr_hash_next(hi))
- {
- const void *key;
-
- apr_hash_this(hi, &key, NULL, NULL);
-
- SVN_ERR(svn_fs_change_node_prop(rb->txn_root, nb->path,
- (const char *) key, NULL,
- nb->pool));
- }
-
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-apply_textdelta(svn_txdelta_window_handler_t *handler,
- void **handler_baton,
- void *node_baton)
-{
- struct node_baton *nb = node_baton;
- struct revision_baton *rb = nb->rb;
-
- return svn_fs_apply_textdelta(handler, handler_baton,
- rb->txn_root, nb->path,
- nb->base_checksum ?
- svn_checksum_to_cstring(nb->base_checksum,
- nb->pool) : NULL,
- nb->result_checksum ?
- svn_checksum_to_cstring(nb->result_checksum,
- nb->pool) : NULL,
- nb->pool);
-}
-
-
-static svn_error_t *
-set_fulltext(svn_stream_t **stream,
- void *node_baton)
-{
- struct node_baton *nb = node_baton;
- struct revision_baton *rb = nb->rb;
-
- return svn_fs_apply_text(stream,
- rb->txn_root, nb->path,
- nb->result_checksum ?
- svn_checksum_to_cstring(nb->result_checksum,
- nb->pool) : NULL,
- nb->pool);
-}
-
-
-static svn_error_t *
-close_node(void *baton)
-{
- struct node_baton *nb = baton;
- struct revision_baton *rb = nb->rb;
- struct parse_baton *pb = rb->pb;
-
- if (pb->notify_func)
- {
- pb->notify->action = svn_repos_notify_load_node_done;
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
- }
-
- return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-close_revision(void *baton)
-{
- struct revision_baton *rb = baton;
- struct parse_baton *pb = rb->pb;
- const char *conflict_msg = NULL;
- svn_revnum_t *old_rev, *new_rev;
- svn_error_t *err;
-
- if (rb->rev <= 0)
- return SVN_NO_ERROR;
-
- /* Prepare memory for saving dump-rev -> in-repos-rev mapping. */
- old_rev = apr_palloc(pb->pool, sizeof(*old_rev) * 2);
- new_rev = old_rev + 1;
- *old_rev = rb->rev;
-
- /* Run the pre-commit hook, if so commanded. */
- if (pb->use_pre_commit_hook)
- {
- const char *txn_name;
- err = svn_fs_txn_name(&txn_name, rb->txn, rb->pool);
- if (! err)
- err = svn_repos__hooks_pre_commit(pb->repos, txn_name, rb->pool);
- if (err)
- {
- svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
- return svn_error_return(err);
- }
- }
-
- /* Commit. */
- if ((err = svn_fs_commit_txn(&conflict_msg, new_rev, rb->txn, rb->pool)))
- {
- svn_error_clear(svn_fs_abort_txn(rb->txn, rb->pool));
- if (conflict_msg)
- return svn_error_quick_wrap(err, conflict_msg);
- else
- return svn_error_return(err);
- }
-
- /* Run post-commit hook, if so commanded. */
- if (pb->use_post_commit_hook)
- {
- if ((err = svn_repos__hooks_post_commit(pb->repos, *new_rev, rb->pool)))
- return svn_error_create
- (SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED, err,
- _("Commit succeeded, but post-commit hook failed"));
- }
-
- /* After a successful commit, must record the dump-rev -> in-repos-rev
- mapping, so that copyfrom instructions in the dump file can look up the
- correct repository revision to copy from. */
- apr_hash_set(pb->rev_map, old_rev, sizeof(svn_revnum_t), new_rev);
-
- /* If the incoming dump stream has non-contiguous revisions (e.g. from
- using svndumpfilter --drop-empty-revs without --renumber-revs) then
- we must account for the missing gaps in PB->REV_MAP. Otherwise we
- might not be able to map all mergeinfo source revisions to the correct
- revisions in the target repos. */
- if (pb->last_rev_mapped != SVN_INVALID_REVNUM
- && *old_rev != pb->last_rev_mapped + 1)
- {
- svn_revnum_t i;
-
- /* Map all dropped revisions between PB->LAST_REV_MAPPED and OLD_REV. */
- for (i = pb->last_rev_mapped + 1; i < *old_rev; i++)
- {
- svn_revnum_t *gap_rev_old = apr_palloc(pb->pool,
- sizeof(*gap_rev_old));
- svn_revnum_t *gap_rev_new = apr_palloc(pb->pool,
- sizeof(*gap_rev_new));
- *gap_rev_old = i;
- *gap_rev_new = pb->last_rev_mapped;
- apr_hash_set(pb->rev_map, gap_rev_old, sizeof(svn_revnum_t),
- gap_rev_new);
- }
- }
- pb->last_rev_mapped = *old_rev;
-
- /* Deltify the predecessors of paths changed in this revision. */
- SVN_ERR(svn_fs_deltify_revision(pb->fs, *new_rev, rb->pool));
-
- /* Grrr, svn_fs_commit_txn rewrites the datestamp property to the
- current clock-time. We don't want that, we want to preserve
- history exactly. Good thing revision props aren't versioned!
- Note that if rb->datestamp is NULL, that's fine -- if the dump
- data doesn't carry a datestamp, we want to preserve that fact in
- the load. */
- SVN_ERR(svn_fs_change_rev_prop(pb->fs, *new_rev,
- SVN_PROP_REVISION_DATE, rb->datestamp,
- rb->pool));
-
- if (pb->notify_func)
- {
- pb->notify->action = svn_repos_notify_load_txn_committed;
- pb->notify->new_revision = *new_rev;
- pb->notify->old_revision = ((*new_rev == rb->rev)
- ? SVN_INVALID_REVNUM
- : rb->rev);
- pb->notify_func(pb->notify_baton, pb->notify, rb->pool);
- }
-
- return SVN_NO_ERROR;
-}
-
-
-/*----------------------------------------------------------------------*/
-
-/** The public routines **/
-
-
-svn_error_t *
-svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks,
- void **parse_baton,
- svn_repos_t *repos,
- svn_boolean_t use_history,
- enum svn_repos_load_uuid uuid_action,
- const char *parent_dir,
- svn_repos_notify_func_t notify_func,
- void *notify_baton,
- apr_pool_t *pool)
-{
- svn_repos_parse_fns2_t *parser = apr_pcalloc(pool, sizeof(*parser));
- struct parse_baton *pb = apr_pcalloc(pool, sizeof(*pb));
-
- parser->new_revision_record = new_revision_record;
- parser->new_node_record = new_node_record;
- parser->uuid_record = uuid_record;
- parser->set_revision_property = set_revision_property;
- parser->set_node_property = set_node_property;
- parser->remove_node_props = remove_node_props;
- parser->set_fulltext = set_fulltext;
- parser->close_node = close_node;
- parser->close_revision = close_revision;
- parser->delete_node_property = delete_node_property;
- parser->apply_textdelta = apply_textdelta;
-
- pb->repos = repos;
- pb->fs = svn_repos_fs(repos);
- pb->use_history = use_history;
- pb->notify_func = notify_func;
- pb->notify_baton = notify_baton;
- pb->notify = svn_repos_notify_create(svn_repos_notify_load_txn_start, pool);
- pb->uuid_action = uuid_action;
- pb->parent_dir = parent_dir;
- pb->pool = pool;
- pb->rev_map = apr_hash_make(pool);
- pb->oldest_old_rev = SVN_INVALID_REVNUM;
- pb->last_rev_mapped = SVN_INVALID_REVNUM;
-
- *callbacks = parser;
- *parse_baton = pb;
- return SVN_NO_ERROR;
-}
-
-
-svn_error_t *
-svn_repos_load_fs3(svn_repos_t *repos,
- svn_stream_t *dumpstream,
- enum svn_repos_load_uuid uuid_action,
- const char *parent_dir,
- svn_boolean_t use_pre_commit_hook,
- svn_boolean_t use_post_commit_hook,
- svn_repos_notify_func_t notify_func,
- void *notify_baton,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
- apr_pool_t *pool)
-{
- const svn_repos_parse_fns2_t *parser;
- void *parse_baton;
- struct parse_baton *pb;
-
- /* This is really simple. */
-
- SVN_ERR(svn_repos_get_fs_build_parser3(&parser, &parse_baton,
- repos,
- TRUE, /* look for copyfrom revs */
- uuid_action,
- parent_dir,
- notify_func,
- notify_baton,
- pool));
-
- /* Heh. We know this is a parse_baton. This file made it. So
- cast away, and set our hook booleans. */
- pb = parse_baton;
- pb->use_pre_commit_hook = use_pre_commit_hook;
- pb->use_post_commit_hook = use_post_commit_hook;
-
- return svn_repos_parse_dumpstream2(dumpstream, parser, parse_baton,
- cancel_func, cancel_baton, pool);
-}
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/log.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/log.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/log.c Thu Dec 2 20:55:08 2010
@@ -1034,7 +1034,10 @@ send_log(svn_revnum_t rev,
memory. */
#define MAX_OPEN_HISTORIES 32
-/* Get the histories for PATHS, and store them in *HISTORIES. */
+/* Get the histories for PATHS, and store them in *HISTORIES.
+
+ If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+ repository locations as fatal -- just ignore them. */
static svn_error_t *
get_path_histories(apr_array_header_t **histories,
svn_fs_t *fs,
@@ -1042,6 +1045,7 @@ get_path_histories(apr_array_header_t **
svn_revnum_t hist_start,
svn_revnum_t hist_end,
svn_boolean_t strict_node_history,
+ svn_boolean_t ignore_missing_locations,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
apr_pool_t *pool)
@@ -1089,7 +1093,18 @@ get_path_histories(apr_array_header_t **
if (i < MAX_OPEN_HISTORIES)
{
- SVN_ERR(svn_fs_node_history(&info->hist, root, this_path, pool));
+ svn_error_t *err;
+ err = svn_fs_node_history(&info->hist, root, this_path, pool);
+ if (err
+ && ignore_missing_locations
+ && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
+ err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
+ err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ SVN_ERR(err);
info->newpool = svn_pool_create(pool);
info->oldpool = svn_pool_create(pool);
}
@@ -1336,6 +1351,7 @@ do_logs(svn_fs_t *fs,
svn_boolean_t discover_changed_paths,
svn_boolean_t strict_node_history,
svn_boolean_t include_merged_revisions,
+ svn_boolean_t ignore_missing_locations,
const apr_array_header_t *revprops,
svn_boolean_t descending_order,
svn_log_entry_receiver_t receiver,
@@ -1383,24 +1399,15 @@ handle_merged_revisions(svn_revnum_t rev
iterpool = svn_pool_create(pool);
for (i = combined_list->nelts - 1; i >= 0; i--)
{
- svn_error_t *err;
struct path_list_range *pl_range
= APR_ARRAY_IDX(combined_list, i, struct path_list_range *);
svn_pool_clear(iterpool);
- err = do_logs(fs, pl_range->paths, pl_range->range.start,
- pl_range->range.end, 0, discover_changed_paths,
- strict_node_history, TRUE, revprops, TRUE,
- receiver, receiver_baton, authz_read_func,
- authz_read_baton, iterpool);
- if (err && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
- err->apr_err == SVN_ERR_FS_NOT_DIRECTORY ||
- err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION))
- {
- svn_error_clear(err);
- continue;
- }
- SVN_ERR(err);
+ SVN_ERR(do_logs(fs, pl_range->paths, pl_range->range.start,
+ pl_range->range.end, 0, discover_changed_paths,
+ strict_node_history, TRUE, TRUE, revprops, TRUE,
+ receiver, receiver_baton, authz_read_func,
+ authz_read_baton, iterpool));
}
svn_pool_destroy(iterpool);
@@ -1415,6 +1422,9 @@ handle_merged_revisions(svn_revnum_t rev
the logs back as we find them, else buffer the logs and send them back
in youngest->oldest order.
+ If IGNORE_MISSING_LOCATIONS is set, don't treat requests for bogus
+ repository locations as fatal -- just ignore them.
+
Other parameters are the same as svn_repos_get_logs4().
*/
static svn_error_t *
@@ -1426,6 +1436,7 @@ do_logs(svn_fs_t *fs,
svn_boolean_t discover_changed_paths,
svn_boolean_t strict_node_history,
svn_boolean_t include_merged_revisions,
+ svn_boolean_t ignore_missing_locations,
const apr_array_header_t *revprops,
svn_boolean_t descending_order,
svn_log_entry_receiver_t receiver,
@@ -1448,8 +1459,8 @@ do_logs(svn_fs_t *fs,
one of our paths was changed. So let's go figure out which
revisions contain real changes to at least one of our paths. */
SVN_ERR(get_path_histories(&histories, fs, paths, hist_start, hist_end,
- strict_node_history, authz_read_func,
- authz_read_baton, pool));
+ strict_node_history, ignore_missing_locations,
+ authz_read_func, authz_read_baton, pool));
/* Loop through all the revisions in the range and add any
where a path was changed to the array, or if they wanted
@@ -1686,7 +1697,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
return do_logs(repos->fs, paths, start, end, limit,
discover_changed_paths, strict_node_history,
- include_merged_revisions, revprops, descending_order,
- receiver, receiver_baton,
+ include_merged_revisions, FALSE, revprops,
+ descending_order, receiver, receiver_baton,
authz_read_func, authz_read_baton, pool);
}
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/replay.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/replay.c Thu Dec 2 20:55:08 2010
@@ -225,8 +225,13 @@ add_subdir(svn_fs_root_t *source_root,
continue;
else if (change->change_kind == svn_fs_path_change_replace)
{
- /* ### Can this assert fail? */
- SVN_ERR_ASSERT(change->copyfrom_known);
+ if (! change->copyfrom_known)
+ {
+ SVN_ERR(svn_fs_copied_from(&change->copyfrom_rev,
+ &change->copyfrom_path,
+ target_root, new_path, pool));
+ change->copyfrom_known = TRUE;
+ }
copyfrom_path = change->copyfrom_path;
copyfrom_rev = change->copyfrom_rev;
}
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/reporter.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/reporter.c Thu Dec 2 20:55:08 2010
@@ -84,6 +84,17 @@ typedef struct path_info_t
apr_pool_t *pool; /* Container pool */
} path_info_t;
+/* Describes the standard revision properties that are relevant for
+ reports. Since a particular revision will often show up more than
+ once in the report, we cache these properties for the time of the
+ report generation. */
+typedef struct revision_info_t
+{
+ svn_revnum_t rev; /* revision number */
+ svn_string_t* date; /* revision timestamp */
+ svn_string_t* author; /* name of the revisions' author */
+} revision_info_t;
+
/* A structure used by the routines within the `reporter' vtable,
driven by the client as it describes its working copy revisions. */
typedef struct report_baton_t
@@ -118,6 +129,11 @@ typedef struct report_baton_t
path_info_t *lookahead;
svn_fs_root_t *t_root;
svn_fs_root_t *s_roots[NUM_CACHED_SOURCE_ROOTS];
+
+ /* Cache for revision properties. This is used to eliminate redundant
+ revprop fetching. */
+ apr_hash_t* revision_infos;
+
apr_pool_t *pool;
} report_baton_t;
@@ -428,6 +444,53 @@ change_file_prop(report_baton_t *b, void
return b->editor->change_file_prop(file_baton, name, value, pool);
}
+/* For the report B, return the relevant revprop data of revision REV in
+ REVISION_INFO. The revision info will be allocated in b->pool.
+ Temporaries get allocated on SCRATCH_POOL. */
+static svn_error_t *
+get_revision_info(report_baton_t *b,
+ svn_revnum_t rev,
+ revision_info_t** revision_info,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *r_props;
+ svn_string_t *cdate, *author;
+ revision_info_t* info;
+
+ /* Try to find the info in the report's cache */
+ info = apr_hash_get(b->revision_infos, &rev, sizeof(rev));
+ if (!info)
+ {
+ /* Info is not available, yet.
+ Get all revprops. */
+ SVN_ERR(svn_fs_revision_proplist(&r_props,
+ b->repos->fs,
+ rev,
+ scratch_pool));
+
+ /* Extract the committed-date. */
+ cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE,
+ APR_HASH_KEY_STRING);
+
+ /* Extract the last-author. */
+ author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,
+ APR_HASH_KEY_STRING);
+
+ /* Create a result object */
+ info = apr_palloc(b->pool, sizeof(*info));
+ info->rev = rev;
+ info->date = cdate ? svn_string_dup(cdate, b->pool) : NULL;
+ info->author = author ? svn_string_dup(author, b->pool) : NULL;
+
+ /* Cache it */
+ apr_hash_set(b->revision_infos, &rev, sizeof(rev), info);
+ }
+
+ *revision_info = info;
+ return SVN_NO_ERROR;
+}
+
+
/* Generate the appropriate property editing calls to turn the
properties of S_REV/S_PATH into those of B->t_root/T_PATH. If
S_PATH is NULL, this is an add, so assume the target starts with no
@@ -440,12 +503,13 @@ delta_proplists(report_baton_t *b, svn_r
void *object, apr_pool_t *pool)
{
svn_fs_root_t *s_root;
- apr_hash_t *s_props, *t_props, *r_props;
+ apr_hash_t *s_props, *t_props;
apr_array_header_t *prop_diffs;
int i;
svn_revnum_t crev;
const char *uuid;
- svn_string_t *cr_str, *cdate, *last_author;
+ svn_string_t *cr_str;
+ revision_info_t* revision_info;
svn_boolean_t changed;
const svn_prop_t *pc;
svn_lock_t *lock;
@@ -459,21 +523,17 @@ delta_proplists(report_baton_t *b, svn_r
SVN_ERR(change_fn(b, object,
SVN_PROP_ENTRY_COMMITTED_REV, cr_str, pool));
- SVN_ERR(svn_fs_revision_proplist(&r_props, b->repos->fs, crev, pool));
+ SVN_ERR(get_revision_info(b, crev, &revision_info, pool));
/* Transmit the committed-date. */
- cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE,
- APR_HASH_KEY_STRING);
- if (cdate || s_path)
+ if (revision_info->date || s_path)
SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_COMMITTED_DATE,
- cdate, pool));
+ revision_info->date, pool));
/* Transmit the last-author. */
- last_author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,
- APR_HASH_KEY_STRING);
- if (last_author || s_path)
+ if (revision_info->author || s_path)
SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_LAST_AUTHOR,
- last_author, pool));
+ revision_info->author, pool));
/* Transmit the UUID. */
SVN_ERR(svn_fs_get_uuid(b->repos->fs, &uuid, pool));
@@ -610,7 +670,7 @@ fake_dirent(const svn_fs_dirent_t **entr
ent = apr_palloc(pool, sizeof(**entry));
/* ### All callers should be updated to pass just one of these
formats */
- ent->name = (*path == '/') ? svn_uri_basename(path, pool)
+ ent->name = (*path == '/') ? svn_fspath__basename(path, pool)
: svn_relpath_basename(path, pool);
SVN_ERR(svn_fs_node_id(&ent->id, root, path, pool));
ent->kind = kind;
@@ -1403,6 +1463,8 @@ svn_repos_begin_report2(void **report_ba
b->edit_baton = edit_baton;
b->authz_read_func = authz_read_func;
b->authz_read_baton = authz_read_baton;
+ b->revision_infos = apr_hash_make(pool);
+ b->pool = pool;
SVN_ERR(svn_io_open_unique_file3(&b->tempfile, NULL, NULL,
svn_io_file_del_on_pool_cleanup,
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/repos.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/repos.c Thu Dec 2 20:55:08 2010
@@ -1141,6 +1141,13 @@ create_conf(svn_repos_t *repos, apr_pool
"### have the same password database, and vice versa. The default realm" NL
"### is repository's uuid." NL
"# realm = My First Repository" NL
+"### The force-username-case option causes svnserve to case-normalize" NL
+"### usernames before comparing them against the authorization rules in the" NL
+"### authz-db file configured above. Valid values are \"upper\" (to upper-" NL
+"### case the usernames), \"lower\" (to lowercase the usernames), and" NL
+"### \"none\" (to compare usernames as-is without case conversion, which" NL
+"### is the default behavior)." NL
+"# force-username-case = none" NL
"" NL
"[sasl]" NL
"### This option specifies whether you want to use the Cyrus SASL" NL
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/rev_hunt.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_repos/rev_hunt.c Thu Dec 2 20:55:08 2010
@@ -1085,47 +1085,49 @@ find_interesting_revisions(apr_array_hea
apr_hash_t *duplicate_path_revs,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- apr_pool_t *iter_pool, *last_pool;
+ apr_pool_t *iterpool, *last_pool;
svn_fs_history_t *history;
svn_fs_root_t *root;
svn_node_kind_t kind;
/* We switch between two pools while looping, since we need information from
the last iteration to be available. */
- iter_pool = svn_pool_create(pool);
- last_pool = svn_pool_create(pool);
+ iterpool = svn_pool_create(scratch_pool);
+ last_pool = svn_pool_create(scratch_pool);
/* The path had better be a file in this revision. */
- SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, last_pool));
- SVN_ERR(svn_fs_check_path(&kind, root, path, pool));
+ SVN_ERR(svn_fs_revision_root(&root, repos->fs, end, scratch_pool));
+ SVN_ERR(svn_fs_check_path(&kind, root, path, scratch_pool));
if (kind != svn_node_file)
return svn_error_createf
(SVN_ERR_FS_NOT_FILE, NULL, _("'%s' is not a file in revision %ld"),
path, end);
/* Open a history object. */
- SVN_ERR(svn_fs_node_history(&history, root, path, last_pool));
-
+ SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
while (1)
{
- struct path_revision *path_rev = apr_palloc(pool, sizeof(*path_rev));
+ struct path_revision *path_rev;
+ svn_revnum_t tmp_revnum;
+ const char *tmp_path;
apr_pool_t *tmp_pool;
- svn_pool_clear(iter_pool);
+ svn_pool_clear(iterpool);
/* Fetch the history object to walk through. */
- SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iter_pool));
+ SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
if (!history)
break;
- SVN_ERR(svn_fs_history_location(&path_rev->path, &path_rev->revnum,
- history, iter_pool));
+ SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
+ history, iterpool));
/* Check to see if we already saw this path (and it's ancestors) */
if (include_merged_revisions
- && is_path_in_hash(duplicate_path_revs, path_rev->path,
- path_rev->revnum, iter_pool))
+ && is_path_in_hash(duplicate_path_revs, tmp_path,
+ tmp_revnum, iterpool))
break;
/* Check authorization. */
@@ -1134,21 +1136,24 @@ find_interesting_revisions(apr_array_hea
svn_boolean_t readable;
svn_fs_root_t *tmp_root;
- SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, path_rev->revnum,
- iter_pool));
- SVN_ERR(authz_read_func(&readable, tmp_root, path_rev->path,
- authz_read_baton, iter_pool));
+ SVN_ERR(svn_fs_revision_root(&tmp_root, repos->fs, tmp_revnum,
+ iterpool));
+ SVN_ERR(authz_read_func(&readable, tmp_root, tmp_path,
+ authz_read_baton, iterpool));
if (! readable)
break;
}
- path_rev->path = apr_pstrdup(pool, path_rev->path);
+ /* We didn't break, so we must really want this path-rev. */
+ path_rev = apr_palloc(result_pool, sizeof(*path_rev));
+ path_rev->path = apr_pstrdup(result_pool, tmp_path);
+ path_rev->revnum = tmp_revnum;
path_rev->merged = mark_as_merged;
APR_ARRAY_PUSH(path_revisions, struct path_revision *) = path_rev;
if (include_merged_revisions)
SVN_ERR(get_merged_mergeinfo(&path_rev->merged_mergeinfo, repos,
- path_rev, pool));
+ path_rev, result_pool));
else
path_rev->merged_mergeinfo = NULL;
@@ -1156,7 +1161,7 @@ find_interesting_revisions(apr_array_hea
occurrences of it. We only care about this if including merged
revisions, 'cause that's the only time we can have duplicates. */
apr_hash_set(duplicate_path_revs,
- apr_psprintf(pool, "%s:%ld", path_rev->path,
+ apr_psprintf(result_pool, "%s:%ld", path_rev->path,
path_rev->revnum),
APR_HASH_KEY_STRING, (void *)0xdeadbeef);
@@ -1164,12 +1169,13 @@ find_interesting_revisions(apr_array_hea
break;
/* Swap pools. */
- tmp_pool = iter_pool;
- iter_pool = last_pool;
+ tmp_pool = iterpool;
+ iterpool = last_pool;
last_pool = tmp_pool;
}
- svn_pool_destroy(iter_pool);
+ svn_pool_destroy(iterpool);
+ svn_pool_destroy(last_pool);
return SVN_NO_ERROR;
}
@@ -1198,12 +1204,12 @@ find_merged_revisions(apr_array_header_t
{
const apr_array_header_t *old;
apr_array_header_t *new;
- apr_pool_t *iter_pool, *last_pool;
+ apr_pool_t *iterpool, *last_pool;
apr_array_header_t *merged_path_revisions = apr_array_make(pool, 0,
sizeof(struct path_revision *));
old = mainline_path_revisions;
- iter_pool = svn_pool_create(pool);
+ iterpool = svn_pool_create(pool);
last_pool = svn_pool_create(pool);
do
@@ -1211,27 +1217,34 @@ find_merged_revisions(apr_array_header_t
int i;
apr_pool_t *temp_pool;
- svn_pool_clear(iter_pool);
- new = apr_array_make(iter_pool, 0, sizeof(struct path_revision *));
+ svn_pool_clear(iterpool);
+ new = apr_array_make(iterpool, 0, sizeof(struct path_revision *));
/* Iterate over OLD, checking for non-empty mergeinfo. If found, gather
path_revisions for any merged revisions, and store those in NEW. */
for (i = 0; i < old->nelts; i++)
{
+ apr_pool_t *iterpool2;
apr_hash_index_t *hi;
struct path_revision *old_pr = APR_ARRAY_IDX(old, i,
struct path_revision *);
if (!old_pr->merged_mergeinfo)
continue;
+ iterpool2 = svn_pool_create(iterpool);
+
/* Determine and trace the merge sources. */
- for (hi = apr_hash_first(iter_pool, old_pr->merged_mergeinfo); hi;
+ for (hi = apr_hash_first(iterpool, old_pr->merged_mergeinfo); hi;
hi = apr_hash_next(hi))
{
+ apr_pool_t *iterpool3;
apr_array_header_t *rangelist;
const char *path;
int j;
+ svn_pool_clear(iterpool2);
+ iterpool3 = svn_pool_create(iterpool2);
+
apr_hash_this(hi, (void *) &path, NULL, (void *) &rangelist);
for (j = 0; j < rangelist->nelts; j++)
@@ -1241,9 +1254,10 @@ find_merged_revisions(apr_array_header_t
svn_node_kind_t kind;
svn_fs_root_t *root;
+ svn_pool_clear(iterpool3);
SVN_ERR(svn_fs_revision_root(&root, repos->fs, range->end,
- iter_pool));
- SVN_ERR(svn_fs_check_path(&kind, root, path, iter_pool));
+ iterpool3));
+ SVN_ERR(svn_fs_check_path(&kind, root, path, iterpool3));
if (kind != svn_node_file)
continue;
@@ -1253,20 +1267,23 @@ find_merged_revisions(apr_array_header_t
TRUE, TRUE,
duplicate_path_revs,
authz_read_func,
- authz_read_baton, pool));
+ authz_read_baton, pool,
+ iterpool3));
}
+ svn_pool_destroy(iterpool3);
}
+ svn_pool_destroy(iterpool2);
}
/* Append the newly found path revisions with the old ones. */
- merged_path_revisions = apr_array_append(iter_pool, merged_path_revisions,
+ merged_path_revisions = apr_array_append(iterpool, merged_path_revisions,
new);
/* Swap data structures */
old = new;
temp_pool = last_pool;
- last_pool = iter_pool;
- iter_pool = temp_pool;
+ last_pool = iterpool;
+ iterpool = temp_pool;
}
while (new->nelts > 0);
@@ -1277,7 +1294,7 @@ find_merged_revisions(apr_array_header_t
/* Copy to the output array. */
*merged_path_revisions_out = apr_array_copy(pool, merged_path_revisions);
- svn_pool_destroy(iter_pool);
+ svn_pool_destroy(iterpool);
svn_pool_destroy(last_pool);
return SVN_NO_ERROR;
@@ -1413,7 +1430,8 @@ svn_repos_get_file_revs2(svn_repos_t *re
SVN_ERR(find_interesting_revisions(mainline_path_revisions, repos, path,
start, end, include_merged_revisions,
FALSE, duplicate_path_revs,
- authz_read_func, authz_read_baton, pool));
+ authz_read_func, authz_read_baton, pool,
+ pool));
/* If we are including merged revisions, go get those, too. */
if (include_merged_revisions)
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/checksum.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/checksum.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/checksum.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/checksum.c Thu Dec 2 20:55:08 2010
@@ -135,6 +135,9 @@ const char *
svn_checksum_to_cstring(const svn_checksum_t *checksum,
apr_pool_t *pool)
{
+ if (checksum == NULL)
+ return NULL;
+
switch (checksum->kind)
{
case svn_checksum_md5:
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_file.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_file.c Thu Dec 2 20:55:08 2010
@@ -38,6 +38,11 @@
#include "svn_private_config.h"
+#ifdef __HAIKU__
+# include <FindDirectory.h>
+# include <StorageDefs.h>
+#endif
+
/* Used to terminate lines in large multi-line string literals. */
#define NL APR_EOL_STR
@@ -331,7 +336,19 @@ svn_config__sys_config_path(const char *
SVN_CONFIG__SUBDIRECTORY, fname, NULL);
}
-#else /* ! WIN32 */
+#elif defined(__HAIKU__)
+ {
+ char folder[B_PATH_NAME_LENGTH];
+
+ status_t error = find_directory(B_COMMON_SETTINGS_DIRECTORY, -1, false,
+ folder, sizeof(folder));
+ if (error)
+ return SVN_NO_ERROR;
+
+ *path_p = svn_dirent_join_many(pool, folder,
+ SVN_CONFIG__SYS_DIRECTORY, fname, NULL);
+ }
+#else /* ! WIN32 && !__HAIKU__ */
*path_p = svn_dirent_join_many(pool, SVN_CONFIG__SYS_DIRECTORY, fname, NULL);
@@ -1118,7 +1135,20 @@ svn_config_get_user_config_path(const ch
SVN_CONFIG__SUBDIRECTORY, fname, NULL);
}
-#else /* ! WIN32 */
+#elif defined(__HAIKU__)
+ {
+ char folder[B_PATH_NAME_LENGTH];
+
+ status_t error = find_directory(B_USER_SETTINGS_DIRECTORY, -1, false,
+ folder, sizeof(folder));
+ if (error)
+ return SVN_NO_ERROR;
+
+ *path = svn_dirent_join_many(pool, folder,
+ SVN_CONFIG__USR_DIRECTORY, fname, NULL);
+ }
+#else /* ! WIN32 && !__HAIKU__ */
+
{
const char *homedir = svn_user_get_homedir(pool);
if (! homedir)
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_impl.h
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_impl.h?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_impl.h (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/config_impl.h Thu Dec 2 20:55:08 2010
@@ -114,7 +114,10 @@ svn_error_t *svn_config__parse_registry(
or svn_config_get_user_config_path() instead. */
#ifdef WIN32
# define SVN_CONFIG__SUBDIRECTORY "Subversion"
-#else /* ! WIN32 */
+#elif defined __HAIKU__ /* HAIKU */
+# define SVN_CONFIG__SYS_DIRECTORY "subversion"
+# define SVN_CONFIG__USR_DIRECTORY "subversion"
+#else /* ! WIN32 && ! __HAIKU__ */
# define SVN_CONFIG__SYS_DIRECTORY "/etc/subversion"
# define SVN_CONFIG__USR_DIRECTORY ".subversion"
#endif /* WIN32 */
Modified: subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/constructors.c
URL: http://svn.apache.org/viewvc/subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/constructors.c?rev=1041580&r1=1041579&r2=1041580&view=diff
==============================================================================
--- subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/constructors.c (original)
+++ subversion/branches/gpg-agent-password-store/subversion/libsvn_subr/constructors.c Thu Dec 2 20:55:08 2010
@@ -45,7 +45,8 @@ svn_commit_info_t *
svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
apr_pool_t *pool)
{
- svn_commit_info_t *dst_commit_info = svn_create_commit_info(pool);
+ svn_commit_info_t *dst_commit_info
+ = apr_palloc(pool, sizeof(*dst_commit_info));
dst_commit_info->date = src_commit_info->date
? apr_pstrdup(pool, src_commit_info->date) : NULL;
@@ -66,6 +67,9 @@ svn_log_changed_path2_create(apr_pool_t
svn_log_changed_path2_t *new_changed_path
= apr_pcalloc(pool, sizeof(*new_changed_path));
+ new_changed_path->text_modified = svn_tristate_unknown;
+ new_changed_path->props_modified = svn_tristate_unknown;
+
return new_changed_path;
}
@@ -74,7 +78,7 @@ svn_log_changed_path2_dup(const svn_log_
apr_pool_t *pool)
{
svn_log_changed_path2_t *new_changed_path
- = svn_log_changed_path2_create(pool);
+ = apr_palloc(pool, sizeof(*new_changed_path));
*new_changed_path = *changed_path;
@@ -190,7 +194,7 @@ svn_log_entry_t *
svn_log_entry_dup(const svn_log_entry_t *log_entry, apr_pool_t *pool)
{
apr_hash_index_t *hi;
- svn_log_entry_t *new_entry = svn_log_entry_create(pool);
+ svn_log_entry_t *new_entry = apr_palloc(pool, sizeof(*new_entry));
*new_entry = *log_entry;
@@ -228,7 +232,8 @@ svn_location_segment_dup(const svn_locat
apr_pool_t *pool)
{
svn_location_segment_t *new_segment =
- apr_pcalloc(pool, sizeof(*new_segment));
+ apr_palloc(pool, sizeof(*new_segment));
+
*new_segment = *segment;
if (segment->path)
new_segment->path = apr_pstrdup(pool, segment->path);