You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/12/10 22:23:13 UTC
svn commit: r1044516 [9/22] - in /subversion/branches/ignore-mergeinfo: ./
build/ac-macros/ build/generator/ contrib/server-side/ notes/ notes/wc-ng/
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/ subver...
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_diff/parse-diff.c Fri Dec 10 21:23:03 2010
@@ -21,7 +21,6 @@
* ====================================================================
*/
-#include <limits.h> /* for ULONG_MAX */
#include <stdlib.h>
#include <string.h>
@@ -29,6 +28,7 @@
#include "svn_error.h"
#include "svn_io.h"
#include "svn_pools.h"
+#include "svn_string.h"
#include "svn_utf.h"
#include "svn_dirent_uri.h"
#include "svn_diff.h"
@@ -39,14 +39,14 @@
#define starts_with(str, start) \
(strncmp((str), (start), strlen(start)) == 0)
-struct svn_hunk_t {
+struct svn_diff_hunk_t {
/* Hunk texts (see include/svn_diff.h). */
svn_stream_t *diff_text;
svn_stream_t *original_text;
svn_stream_t *modified_text;
- /* Whether the hunk is being interpreted in reverse. */
- svn_boolean_t reverse;
+ /* The patch this hunk belongs to. */
+ svn_patch_t *patch;
/* Hunk ranges as they appeared in the patch file.
* All numbers are lines, not bytes. */
@@ -61,55 +61,61 @@ struct svn_hunk_t {
};
svn_error_t *
-svn_diff_hunk_reset_diff_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_diff_text(const svn_diff_hunk_t *hunk)
{
return svn_error_return(svn_stream_reset(hunk->diff_text));
}
svn_error_t *
-svn_diff_hunk_reset_original_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_original_text(const svn_diff_hunk_t *hunk)
{
- return svn_error_return(svn_stream_reset(hunk->original_text));
+ if (hunk->patch->reverse)
+ return svn_error_return(svn_stream_reset(hunk->modified_text));
+ else
+ return svn_error_return(svn_stream_reset(hunk->original_text));
}
svn_error_t *
-svn_diff_hunk_reset_modified_text(const svn_hunk_t *hunk)
+svn_diff_hunk_reset_modified_text(const svn_diff_hunk_t *hunk)
{
- return svn_error_return(svn_stream_reset(hunk->modified_text));
+ if (hunk->patch->reverse)
+ return svn_error_return(svn_stream_reset(hunk->original_text));
+ else
+ return svn_error_return(svn_stream_reset(hunk->modified_text));
}
svn_linenum_t
-svn_diff_hunk_get_original_start(const svn_hunk_t *hunk)
+svn_diff_hunk_get_original_start(const svn_diff_hunk_t *hunk)
{
- return hunk->original_start;
+ return hunk->patch->reverse ? hunk->modified_start : hunk->original_start;
}
svn_linenum_t
-svn_diff_hunk_get_original_length(const svn_hunk_t *hunk)
+svn_diff_hunk_get_original_length(const svn_diff_hunk_t *hunk)
{
- return hunk->original_length;
+ return hunk->patch->reverse ? hunk->modified_length : hunk->original_length;
}
svn_linenum_t
-svn_diff_hunk_get_modified_start(const svn_hunk_t *hunk)
+svn_diff_hunk_get_modified_start(const svn_diff_hunk_t *hunk)
{
- return hunk->modified_start;
+ return hunk->patch->reverse ? hunk->original_start : hunk->modified_start;
}
svn_linenum_t
-svn_diff_hunk_get_modified_length(const svn_hunk_t *hunk)
+svn_diff_hunk_get_modified_length(const svn_diff_hunk_t *hunk)
{
- return hunk->modified_length;
+ return hunk->patch->reverse ? hunk->original_length : hunk->modified_length;
}
svn_linenum_t
-svn_diff_hunk_get_leading_context(const svn_hunk_t *hunk)
+svn_diff_hunk_get_leading_context(const svn_diff_hunk_t *hunk)
{
return hunk->leading_context;
}
svn_linenum_t
-svn_diff_hunk_get_trailing_context(const svn_hunk_t *hunk)
+svn_diff_hunk_get_trailing_context(const svn_diff_hunk_t *hunk)
{
return hunk->trailing_context;
}
@@ -120,20 +126,18 @@ svn_diff_hunk_get_trailing_context(const
static svn_boolean_t
parse_offset(svn_linenum_t *offset, const char *number)
{
- apr_int64_t parsed_offset;
+ svn_error_t *err;
+ apr_uint64_t val;
- errno = 0; /* apr_atoi64() in APR-0.9 does not always set errno */
- parsed_offset = apr_atoi64(number);
- if (errno == ERANGE || parsed_offset < 0)
- return FALSE;
+ err = svn_cstring_strtoui64(&val, number, 0, SVN_LINENUM_MAX_VALUE, 10);
+ if (err)
+ {
+ svn_error_clear(err);
+ return FALSE;
+ }
- /* In case we cannot fit 64 bits into an svn_linenum_t,
- * check for overflow. */
- if (sizeof(svn_linenum_t) < sizeof(parsed_offset) &&
- parsed_offset > SVN_LINENUM_MAX_VALUE)
- return FALSE;
+ *offset = (svn_linenum_t)val;
- *offset = parsed_offset;
return TRUE;
}
@@ -179,11 +183,10 @@ parse_range(svn_linenum_t *start, svn_li
/* Try to parse a hunk header in string HEADER, putting parsed information
* into HUNK. Return TRUE if the header parsed correctly. ATAT is the
* character string used to delimit the hunk header.
- * If REVERSE is TRUE, invert the hunk header while parsing it.
* Do all allocations in POOL. */
static svn_boolean_t
-parse_hunk_header(const char *header, svn_hunk_t *hunk,
- const char *atat, svn_boolean_t reverse, apr_pool_t *pool)
+parse_hunk_header(const char *header, svn_diff_hunk_t *hunk,
+ const char *atat, apr_pool_t *pool)
{
const char *p;
svn_stringbuf_t *range;
@@ -201,7 +204,7 @@ parse_hunk_header(const char *header, sv
p++;
while (*p && *p != ' ')
{
- svn_stringbuf_appendbytes(range, p, 1);
+ svn_stringbuf_appendbyte(range, *p);
p++;
}
if (*p != ' ')
@@ -209,16 +212,8 @@ parse_hunk_header(const char *header, sv
return FALSE;
/* Try to parse the first range. */
- if (reverse)
- {
- if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
- return FALSE;
- }
- else
- {
- if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
- return FALSE;
- }
+ if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
+ return FALSE;
/* Clear the stringbuf so we can reuse it for the second range. */
svn_stringbuf_setempty(range);
@@ -230,7 +225,7 @@ parse_hunk_header(const char *header, sv
p++;
while (*p && *p != ' ')
{
- svn_stringbuf_appendbytes(range, p, 1);
+ svn_stringbuf_appendbyte(range, *p);
p++;
}
if (*p != ' ')
@@ -246,16 +241,8 @@ parse_hunk_header(const char *header, sv
* but we ignore that. */
/* Try to parse the second range. */
- if (reverse)
- {
- if (! parse_range(&hunk->original_start, &hunk->original_length, range->data))
- return FALSE;
- }
- else
- {
- if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
- return FALSE;
- }
+ if (! parse_range(&hunk->modified_start, &hunk->modified_length, range->data))
+ return FALSE;
/* Hunk header is good. */
return TRUE;
@@ -374,7 +361,7 @@ hunk_readline(svn_stream_t *stream,
else
match = eol_str;
- svn_stringbuf_appendbytes(str, &c, 1);
+ svn_stringbuf_appendbyte(str, c);
}
svn_stringbuf_chop(str, match - eol_str);
@@ -407,48 +394,54 @@ hunk_readline(svn_stream_t *stream,
}
svn_error_t *
-svn_diff_hunk_readline_original_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_original_text(const svn_diff_hunk_t *hunk,
svn_stringbuf_t **stringbuf,
const char **eol,
svn_boolean_t *eof,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_error_return(hunk_readline(hunk->original_text, stringbuf,
- eol, eof, hunk->reverse ? '-' : '+',
+ return svn_error_return(hunk_readline(hunk->patch->reverse ?
+ hunk->modified_text :
+ hunk->original_text,
+ stringbuf, eol, eof,
+ hunk->patch->reverse ? '-' : '+',
result_pool, scratch_pool));
}
svn_error_t *
-svn_diff_hunk_readline_modified_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_modified_text(const svn_diff_hunk_t *hunk,
svn_stringbuf_t **stringbuf,
const char **eol,
svn_boolean_t *eof,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- return svn_error_return(hunk_readline(hunk->modified_text, stringbuf,
- eol, eof, hunk->reverse ? '+' : '-',
+ return svn_error_return(hunk_readline(hunk->patch->reverse ?
+ hunk->original_text :
+ hunk->modified_text,
+ stringbuf, eol, eof,
+ hunk->patch->reverse ? '+' : '-',
result_pool, scratch_pool));
}
svn_error_t *
-svn_diff_hunk_readline_diff_text(const svn_hunk_t *hunk,
+svn_diff_hunk_readline_diff_text(const svn_diff_hunk_t *hunk,
svn_stringbuf_t **stringbuf,
const char **eol,
svn_boolean_t *eof,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_hunk_t dummy;
+ svn_diff_hunk_t dummy;
svn_stringbuf_t *line;
SVN_ERR(svn_stream_readline_detect_eol(hunk->diff_text, &line, eol, eof,
result_pool));
- if (hunk->reverse)
+ if (hunk->patch->reverse)
{
- if (parse_hunk_header(line->data, &dummy, "@@", FALSE, scratch_pool))
+ if (parse_hunk_header(line->data, &dummy, "@@", scratch_pool))
{
/* Line is a hunk header, reverse it. */
*stringbuf = svn_stringbuf_createf(result_pool,
@@ -458,7 +451,7 @@ svn_diff_hunk_readline_diff_text(const s
hunk->original_start,
hunk->original_length);
}
- else if (parse_hunk_header(line->data, &dummy, "##", FALSE, scratch_pool))
+ else if (parse_hunk_header(line->data, &dummy, "##", scratch_pool))
{
/* Line is a hunk header, reverse it. */
*stringbuf = svn_stringbuf_createf(result_pool,
@@ -489,6 +482,8 @@ static svn_error_t *
parse_prop_name(const char **prop_name, const char *header,
const char *indicator, apr_pool_t *result_pool)
{
+ /* ### This can fail if the filename cannot be represented in the current
+ * ### locale's encoding. */
SVN_ERR(svn_utf_cstring_to_utf8(prop_name,
header + strlen(indicator),
result_pool));
@@ -504,18 +499,16 @@ parse_prop_name(const char **prop_name,
* IS_PROPERTY to TRUE if we have a property hunk. If the returned HUNK is
* the first belonging to a certain property, then PROP_NAME and
* PROP_OPERATION will be set too. If we have a text hunk, PROP_NAME will be
- * NULL. If REVERSE is TRUE, invert the hunk while parsing it. If
- * IGNORE_WHiTESPACES is TRUE, let lines without leading spaces be
+ * NULL. If IGNORE_WHITESPACE is TRUE, let lines without leading spaces be
* recognized as context lines. Allocate results in
* RESULT_POOL. Use SCRATCH_POOL for all other allocations. */
static svn_error_t *
-parse_next_hunk(svn_hunk_t **hunk,
+parse_next_hunk(svn_diff_hunk_t **hunk,
svn_boolean_t *is_property,
const char **prop_name,
svn_diff_operation_kind_t *prop_operation,
svn_patch_t *patch,
svn_stream_t *stream,
- svn_boolean_t reverse,
svn_boolean_t ignore_whitespace,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
@@ -588,19 +581,8 @@ parse_next_hunk(svn_hunk_t **hunk,
if (in_hunk)
{
char c;
- char add;
- char del;
-
- if (reverse)
- {
- add = '-';
- del = '+';
- }
- else
- {
- add = '+';
- del = '-';
- }
+ static const char add = '+';
+ static const char del = '-';
if (! hunk_seen)
{
@@ -661,11 +643,14 @@ parse_next_hunk(svn_hunk_t **hunk,
}
else
{
+ /* ### Add an is_hunk_header() helper function that returns
+ * ### the proper atat string? Then we could collapse the
+ * ### following two if-clauses. */
if (starts_with(line->data, text_atat))
{
/* Looks like we have a hunk header, try to rip it apart. */
in_hunk = parse_hunk_header(line->data, *hunk, text_atat,
- reverse, iterpool);
+ iterpool);
if (in_hunk)
{
original_lines = (*hunk)->original_length;
@@ -678,7 +663,7 @@ parse_next_hunk(svn_hunk_t **hunk,
/* Looks like we have a property hunk header, try to rip it
* apart. */
in_hunk = parse_hunk_header(line->data, *hunk, prop_atat,
- reverse, iterpool);
+ iterpool);
if (in_hunk)
{
original_lines = (*hunk)->original_length;
@@ -705,7 +690,7 @@ parse_next_hunk(svn_hunk_t **hunk,
*prop_operation = svn_diff_op_modified;
}
else if (starts_with(line->data, minus)
- || starts_with(line->data, "git --diff "))
+ || starts_with(line->data, "diff --git "))
/* This could be a header of another patch. Bail out. */
break;
}
@@ -749,7 +734,7 @@ parse_next_hunk(svn_hunk_t **hunk,
result_pool);
(*hunk)->diff_text = diff_text;
- (*hunk)->reverse = reverse;
+ (*hunk)->patch = patch;
(*hunk)->original_text = original_text;
(*hunk)->modified_text = modified_text;
(*hunk)->leading_context = leading_context;
@@ -767,8 +752,8 @@ parse_next_hunk(svn_hunk_t **hunk,
static int
compare_hunks(const void *a, const void *b)
{
- const svn_hunk_t *ha = *((const svn_hunk_t **)a);
- const svn_hunk_t *hb = *((const svn_hunk_t **)b);
+ const svn_diff_hunk_t *ha = *((const svn_diff_hunk_t *const *)a);
+ const svn_diff_hunk_t *hb = *((const svn_diff_hunk_t *const *)b);
if (ha->original_start < hb->original_start)
return -1;
@@ -781,7 +766,7 @@ compare_hunks(const void *a, const void
* Ensure that all streams which were opened for HUNK are closed.
*/
static svn_error_t *
-close_hunk(const svn_hunk_t *hunk)
+close_hunk(const svn_diff_hunk_t *hunk)
{
SVN_ERR(svn_stream_close(hunk->original_text));
SVN_ERR(svn_stream_close(hunk->modified_text));
@@ -789,27 +774,30 @@ close_hunk(const svn_hunk_t *hunk)
return SVN_NO_ERROR;
}
+/* Possible states of the diff header parser. */
enum parse_state
{
- state_start,
- state_git_diff_seen,
- /* if we have an add || del || cp src+dst || mv src+dst */
- state_git_tree_seen,
- state_git_minus_seen,
- state_git_plus_seen,
- state_move_from_seen,
- state_copy_from_seen,
- state_minus_seen,
- state_unidiff_found,
- state_add_seen,
- state_del_seen,
- state_git_header_found
+ state_start, /* initial */
+ state_git_diff_seen, /* diff --git */
+ state_git_tree_seen, /* a tree operation, rather then content change */
+ state_git_minus_seen, /* --- /dev/null; or --- a/ */
+ state_git_plus_seen, /* +++ /dev/null; or +++ a/ */
+ state_move_from_seen, /* rename from foo.c */
+ state_copy_from_seen, /* copy from foo.c */
+ state_minus_seen, /* --- foo.c */
+ state_unidiff_found, /* valid start of a regular unidiff header */
+ state_add_seen, /* ### unused? */
+ state_del_seen, /* ### unused? */
+ state_git_header_found /* valid start of a --git diff header */
};
+/* Data type describing a valid state transition of the parser. */
struct transition
{
const char *expected_input;
enum parse_state required_state;
+
+ /* A callback called upon each parser state transition. */
svn_error_t *(*fn)(enum parse_state *new_state, const char *input,
svn_patch_t *patch, apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -826,6 +814,8 @@ grab_filename(const char **file_name, co
/* Grab the filename and encode it in UTF-8. */
/* TODO: Allow specifying the patch file's encoding.
* For now, we assume its encoding is native. */
+ /* ### This can fail if the filename cannot be represented in the current
+ * ### locale's encoding. */
SVN_ERR(svn_utf_cstring_to_utf8(&utf8_path,
line,
scratch_pool));
@@ -896,7 +886,8 @@ git_start(enum parse_state *new_state, c
* such substitution then the whole pathname is put in double quotes.
*/
- /* Our line should look like this: 'git --diff a/path b/path'.
+ /* Our line should look like this: 'diff --git a/path b/path'.
+ *
* If we find any deviations from that format, we return with state reset
* to start.
*/
@@ -931,9 +922,9 @@ git_start(enum parse_state *new_state, c
/* By now, we know that we have a line on the form '--git diff a/.+ b/.+'
* We only need the filenames when we have deleted or added empty
* files. In those cases the old_path and new_path is identical on the
- * '--git diff' line. For all other cases we fetch the filenames from
+ * 'diff --git' line. For all other cases we fetch the filenames from
* other header lines. */
- old_path_start = line + strlen("--git diff a/");
+ old_path_start = line + strlen("diff --git a/");
new_path_end = line + strlen(line);
new_path_start = old_path_start;
@@ -1011,7 +1002,7 @@ git_plus(enum parse_state *new_state, co
* the rest of the line which we can discard. */
char *tab = strchr(line, '\t');
if (tab)
- *tab = '\0';
+ *tab = '\0'; /* ### indirectly modifying LINE, which is const */
if (starts_with(line, "+++ /dev/null"))
SVN_ERR(grab_filename(&patch->new_filename, "/dev/null",
@@ -1024,7 +1015,7 @@ git_plus(enum parse_state *new_state, co
return SVN_NO_ERROR;
}
-/* Parse the 'move from ' line of a git extended unidiff. */
+/* Parse the 'rename from ' line of a git extended unidiff. */
static svn_error_t *
git_move_from(enum parse_state *new_state, const char *line, svn_patch_t *patch,
apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -1036,7 +1027,7 @@ git_move_from(enum parse_state *new_stat
return SVN_NO_ERROR;
}
-/* Parse the 'move to ' line fo a git extended unidiff. */
+/* Parse the 'rename to ' line fo a git extended unidiff. */
static svn_error_t *
git_move_to(enum parse_state *new_state, const char *line, svn_patch_t *patch,
apr_pool_t *result_pool, apr_pool_t *scratch_pool)
@@ -1083,6 +1074,8 @@ git_new_file(enum parse_state *new_state
{
patch->operation = svn_diff_op_added;
+ /* Filename already retrieved from diff --git header. */
+
*new_state = state_git_tree_seen;
return SVN_NO_ERROR;
}
@@ -1094,6 +1087,8 @@ git_deleted_file(enum parse_state *new_s
{
patch->operation = svn_diff_op_deleted;
+ /* Filename already retrieved from diff --git header. */
+
*new_state = state_git_tree_seen;
return SVN_NO_ERROR;
}
@@ -1101,7 +1096,7 @@ git_deleted_file(enum parse_state *new_s
/* Add a HUNK associated with the property PROP_NAME to PATCH. */
static svn_error_t *
add_property_hunk(svn_patch_t *patch, const char *prop_name,
- svn_hunk_t *hunk, svn_diff_operation_kind_t operation,
+ svn_diff_hunk_t *hunk, svn_diff_operation_kind_t operation,
apr_pool_t *result_pool)
{
svn_prop_patch_t *prop_patch;
@@ -1114,13 +1109,14 @@ add_property_hunk(svn_patch_t *patch, co
prop_patch = apr_palloc(result_pool, sizeof(svn_prop_patch_t));
prop_patch->name = prop_name;
prop_patch->operation = operation;
- prop_patch->hunks = apr_array_make(result_pool, 1, sizeof(svn_hunk_t *));
+ prop_patch->hunks = apr_array_make(result_pool, 1,
+ sizeof(svn_diff_hunk_t *));
apr_hash_set(patch->prop_patches, prop_name, APR_HASH_KEY_STRING,
prop_patch);
}
- APR_ARRAY_PUSH(prop_patch->hunks, svn_hunk_t *) = hunk;
+ APR_ARRAY_PUSH(prop_patch->hunks, svn_diff_hunk_t *) = hunk;
return SVN_NO_ERROR;
}
@@ -1149,7 +1145,7 @@ svn_diff_parse_next_patch(svn_patch_t **
{
{"--- ", state_start, diff_minus},
{"+++ ", state_minus_seen, diff_plus},
- {"git --diff", state_start, git_start},
+ {"diff --git", state_start, git_start},
{"--- a/", state_git_diff_seen, git_minus},
{"--- a/", state_git_tree_seen, git_minus},
{"--- /dev/null", state_git_tree_seen, git_minus},
@@ -1244,6 +1240,7 @@ svn_diff_parse_next_patch(svn_patch_t **
} while (! eof);
+ (*patch)->reverse = reverse;
if (reverse)
{
const char *temp;
@@ -1259,21 +1256,22 @@ svn_diff_parse_next_patch(svn_patch_t **
}
else
{
- svn_hunk_t *hunk;
+ svn_diff_hunk_t *hunk;
svn_boolean_t is_property;
const char *last_prop_name;
const char *prop_name;
svn_diff_operation_kind_t prop_operation;
/* Parse hunks. */
- (*patch)->hunks = apr_array_make(result_pool, 10, sizeof(svn_hunk_t *));
+ (*patch)->hunks = apr_array_make(result_pool, 10,
+ sizeof(svn_diff_hunk_t *));
(*patch)->prop_patches = apr_hash_make(result_pool);
do
{
svn_pool_clear(iterpool);
SVN_ERR(parse_next_hunk(&hunk, &is_property, &prop_name,
- &prop_operation, *patch, stream, reverse,
+ &prop_operation, *patch, stream,
ignore_whitespace,
result_pool, iterpool));
@@ -1288,7 +1286,7 @@ svn_diff_parse_next_patch(svn_patch_t **
}
else if (hunk)
{
- APR_ARRAY_PUSH((*patch)->hunks, svn_hunk_t *) = hunk;
+ APR_ARRAY_PUSH((*patch)->hunks, svn_diff_hunk_t *) = hunk;
last_prop_name = NULL;
}
@@ -1313,15 +1311,34 @@ svn_diff_parse_next_patch(svn_patch_t **
}
svn_error_t *
-svn_diff_close_patch(const svn_patch_t *patch)
+svn_diff_close_patch(const svn_patch_t *patch, apr_pool_t *scratch_pool)
{
int i;
+ apr_hash_index_t *hi;
for (i = 0; i < patch->hunks->nelts; i++)
{
- const svn_hunk_t *hunk = APR_ARRAY_IDX(patch->hunks, i, svn_hunk_t *);
+ const svn_diff_hunk_t *hunk = APR_ARRAY_IDX(patch->hunks, i,
+ svn_diff_hunk_t *);
SVN_ERR(close_hunk(hunk));
}
+ for (hi = apr_hash_first(scratch_pool, patch->prop_patches);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ svn_prop_patch_t *prop_patch;
+
+ prop_patch = svn__apr_hash_index_val(hi);
+
+ for (i = 0; i < prop_patch->hunks->nelts; i++)
+ {
+ const svn_diff_hunk_t *hunk;
+
+ hunk = APR_ARRAY_IDX(prop_patch->hunks, i, svn_diff_hunk_t *);
+ SVN_ERR(close_hunk(hunk));
+ }
+ }
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs/access.c Fri Dec 10 21:23:03 2010
@@ -87,7 +87,7 @@ svn_fs_access_add_lock_token2(svn_fs_acc
const char *token)
{
apr_hash_set(access_ctx->lock_tokens,
- token, APR_HASH_KEY_STRING, (void *) path);
+ token, APR_HASH_KEY_STRING, path);
return SVN_NO_ERROR;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/fs-history Fri Dec 10 21:23:03 2010
@@ -63,7 +63,7 @@ under-the-hood is as follows:
1. The root refers to a particular snapshot of the DAG node tree,
and from this we can learn the node-revision ID of the node
which represents the root directory ("/") as it appears in that
- snaphot. Given this node-revision ID, it's all DAG from here.
+ snapshot. Given this node-revision ID, it's all DAG from here.
2. The path is split into components and traversed, beginning with
the root node, and walking down toward the full path. Each
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/notes/structure Fri Dec 10 21:23:03 2010
@@ -141,7 +141,7 @@ Note that a node cannot change its kind
A directory node is always a directory; a file node is always a file;
etc. The fact that the node's kind is stored in each node revision,
rather than in some revision-independent place, might suggest that
-it's possible for a node change kinds from revision to revision, but
+it's possible for a node to change kinds from revision to revision, but
Subversion does not allow this.
PROP-KEY is a key into the `representations' table (see REPRESENTATIONS
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/revs-txns.c Fri Dec 10 21:23:03 2010
@@ -270,7 +270,7 @@ svn_fs_base__set_rev_prop(svn_fs_t *fs,
&& !svn_string_compare(wanted_value, present_value)))
{
/* What we expected isn't what we found. */
- return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+ return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
_("revprop '%s' has unexpected value in "
"filesystem"),
name);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_base/util/fs_skels.c Fri Dec 10 21:23:03 2010
@@ -31,6 +31,7 @@
#include "svn_time.h"
#include "private/svn_skel.h"
+#include "private/svn_dep_compat.h"
#include "svn_checksum.h"
#include "fs_skels.h"
@@ -550,32 +551,38 @@ svn_fs_base__parse_representation_skel(r
{
svn_skel_t *window_skel = chunk_skel->children->next;
svn_skel_t *diff_skel = window_skel->children;
+ apr_int64_t val;
+ apr_uint64_t uval;
+ const char *str;
/* Allocate a chunk and its window */
chunk = apr_palloc(pool, sizeof(*chunk));
/* Populate the window */
- chunk->version
- = (apr_byte_t)atoi(apr_pstrmemdup
- (pool,
- diff_skel->children->next->data,
- diff_skel->children->next->len));
+ str = apr_pstrmemdup(pool, diff_skel->children->next->data,
+ diff_skel->children->next->len);
+ SVN_ERR(svn_cstring_strtoui64(&uval, str, 0, 255, 10));
+ chunk->version = (apr_byte_t)uval;
+
chunk->string_key
= apr_pstrmemdup(pool,
diff_skel->children->next->next->data,
diff_skel->children->next->next->len);
- chunk->size
- = atoi(apr_pstrmemdup(pool,
- window_skel->children->next->data,
- window_skel->children->next->len));
+
+ str = apr_pstrmemdup(pool, window_skel->children->next->data,
+ window_skel->children->next->len);
+ SVN_ERR(svn_cstring_strtoui64(&uval, str, 0, APR_SIZE_MAX, 10));
+ chunk->size = (apr_size_t)uval;
+
chunk->rep_key
= apr_pstrmemdup(pool,
window_skel->children->next->next->data,
window_skel->children->next->next->len);
- chunk->offset =
- svn__atoui64(apr_pstrmemdup(pool,
- chunk_skel->children->data,
- chunk_skel->children->len));
+
+ str = apr_pstrmemdup(pool, chunk_skel->children->data,
+ chunk_skel->children->len);
+ SVN_ERR(svn_cstring_strtoi64(&val, str, 0, APR_INT64_MAX, 10));
+ chunk->offset = (svn_filesize_t)val;
/* Add this chunk to the array. */
APR_ARRAY_PUSH(chunks, rep_delta_chunk_t *) = chunk;
@@ -633,24 +640,28 @@ svn_fs_base__parse_node_revision_skel(no
noderev->predecessor_count = -1;
if (cur_skel->next)
{
+ const char *str;
+
cur_skel = cur_skel->next;
if (cur_skel->len)
- noderev->predecessor_count = atoi(apr_pstrmemdup(pool,
- cur_skel->data,
- cur_skel->len));
+ {
+ str = apr_pstrmemdup(pool, cur_skel->data, cur_skel->len);
+ SVN_ERR(svn_cstring_atoi(&noderev->predecessor_count, str));
+ }
/* HAS-MERGEINFO and MERGEINFO-COUNT */
if (cur_skel->next)
{
+ int val;
+
cur_skel = cur_skel->next;
- noderev->has_mergeinfo = atoi(apr_pstrmemdup(pool,
- cur_skel->data,
- cur_skel->len))
- != 0;
- noderev->mergeinfo_count =
- apr_atoi64(apr_pstrmemdup(pool,
- cur_skel->next->data,
- cur_skel->next->len));
+ str = apr_pstrmemdup(pool, cur_skel->data, cur_skel->len);
+ SVN_ERR(svn_cstring_atoi(&val, str));
+ noderev->has_mergeinfo = (val != 0);
+
+ str = apr_pstrmemdup(pool, cur_skel->next->data,
+ cur_skel->next->len);
+ SVN_ERR(svn_cstring_atoi64(&noderev->mergeinfo_count, str));
}
}
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/fs_fs.c Fri Dec 10 21:23:03 2010
@@ -44,9 +44,11 @@
#include "svn_hash.h"
#include "svn_props.h"
#include "svn_sorts.h"
+#include "svn_string.h"
#include "svn_time.h"
#include "svn_mergeinfo.h"
#include "svn_config.h"
+#include "svn_ctype.h"
#include "fs.h"
#include "err.h"
@@ -150,6 +152,9 @@ read_min_unpacked_rev(svn_revnum_t *min_
static svn_error_t *
update_min_unpacked_rev(svn_fs_t *fs, apr_pool_t *pool);
+static svn_error_t *
+update_min_unpacked_revprop(svn_fs_t *fs, apr_pool_t *pool);
+
/* Pathname helper functions */
/* Return TRUE is REV is packed in FS, FALSE otherwise. */
@@ -567,7 +572,8 @@ get_lock_on_filesystem(const char *lock_
BATON and that subpool, destroy the subpool (releasing the write
lock) and return what BODY returned. */
static svn_error_t *
-with_some_lock(svn_error_t *(*body)(void *baton,
+with_some_lock(svn_fs_t *fs,
+ svn_error_t *(*body)(void *baton,
apr_pool_t *pool),
void *baton,
const char *lock_filename,
@@ -594,7 +600,14 @@ with_some_lock(svn_error_t *(*body)(void
err = get_lock_on_filesystem(lock_filename, subpool);
if (!err)
- err = body(baton, subpool);
+ {
+ fs_fs_data_t *ffd = fs->fsap_data;
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
+ SVN_ERR(update_min_unpacked_rev(fs, pool));
+ if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+ SVN_ERR(update_min_unpacked_revprop(fs, pool));
+ err = body(baton, subpool);
+ }
svn_pool_destroy(subpool);
@@ -622,7 +635,7 @@ svn_fs_fs__with_write_lock(svn_fs_t *fs,
apr_thread_mutex_t *mutex = ffsd->fs_write_lock;
#endif
- return with_some_lock(body, baton,
+ return with_some_lock(fs, body, baton,
path_lock(fs, pool),
#if SVN_FS_FS__USE_LOCK_MUTEX
mutex,
@@ -645,7 +658,7 @@ with_txn_current_lock(svn_fs_t *fs,
apr_thread_mutex_t *mutex = ffsd->txn_current_lock;
#endif
- return with_some_lock(body, baton,
+ return with_some_lock(fs, body, baton,
path_txn_current_lock(fs, pool),
#if SVN_FS_FS__USE_LOCK_MUTEX
mutex,
@@ -894,21 +907,21 @@ get_file_offset(apr_off_t *offset_p, apr
}
-/* Check that BUF, a buffer of text from format file PATH, contains
- only digits, raising error SVN_ERR_BAD_VERSION_FILE_FORMAT if not.
+/* Check that BUF, a nul-terminated buffer of text from format file PATH,
+ contains only digits at OFFSET and beyond, raising an error if not.
Uses POOL for temporary allocation. */
static svn_error_t *
-check_format_file_buffer_numeric(const char *buf, const char *path,
- apr_pool_t *pool)
+check_format_file_buffer_numeric(const char *buf, apr_off_t offset,
+ const char *path, apr_pool_t *pool)
{
const char *p;
- for (p = buf; *p; p++)
- if (!apr_isdigit(*p))
+ for (p = buf + offset; *p; p++)
+ if (!svn_ctype_isdigit(*p))
return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
- _("Format file '%s' contains an unexpected non-digit"),
- svn_dirent_local_style(path, pool));
+ _("Format file '%s' contains unexpected non-digit '%c' within '%s'"),
+ svn_dirent_local_style(path, pool), *p, buf);
return SVN_NO_ERROR;
}
@@ -962,8 +975,8 @@ read_format(int *pformat, int *max_files
SVN_ERR(err);
/* Check that the first line contains only digits. */
- SVN_ERR(check_format_file_buffer_numeric(buf, path, pool));
- *pformat = atoi(buf);
+ SVN_ERR(check_format_file_buffer_numeric(buf, 0, path, pool));
+ SVN_ERR(svn_cstring_atoi(pformat, buf));
/* Set the default values for anything that can be set via an option. */
*max_files_per_dir = 0;
@@ -993,8 +1006,8 @@ read_format(int *pformat, int *max_files
if (strncmp(buf+7, "sharded ", 8) == 0)
{
/* Check that the argument is numeric. */
- SVN_ERR(check_format_file_buffer_numeric(buf+15, path, pool));
- *max_files_per_dir = atoi(buf+15);
+ SVN_ERR(check_format_file_buffer_numeric(buf, 15, path, pool));
+ SVN_ERR(svn_cstring_atoi(max_files_per_dir, buf + 15));
continue;
}
}
@@ -1933,18 +1946,20 @@ get_packed_offset(apr_off_t *rev_offset,
{
svn_stringbuf_t *sb;
svn_boolean_t eof;
+ apr_int64_t val;
+ svn_error_t *err;
svn_pool_clear(iterpool);
SVN_ERR(svn_stream_readline(manifest_stream, &sb, "\n", &eof, iterpool));
if (eof)
break;
- errno = 0; /* apr_atoi64() in APR-0.9 does not always set errno */
- APR_ARRAY_PUSH(manifest, apr_off_t) =
- apr_atoi64(svn_string_create_from_buf(sb, iterpool)->data);
- if (errno == ERANGE)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- "Manifest offset too large");
+ err = svn_cstring_atoi64(&val, sb->data);
+ if (err)
+ return svn_error_return(
+ svn_error_create(SVN_ERR_FS_CORRUPT, err,
+ _("Manifest offset too large")));
+ APR_ARRAY_PUSH(manifest, apr_off_t) = (apr_off_t)val;
}
svn_pool_destroy(iterpool);
@@ -2045,6 +2060,7 @@ read_rep_offsets(representation_t **rep_
{
representation_t *rep;
char *str, *last_str;
+ apr_int64_t val;
rep = apr_pcalloc(pool, sizeof(*rep));
*rep_p = rep;
@@ -2068,21 +2084,24 @@ read_rep_offsets(representation_t **rep_
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Malformed text representation offset line in node-rev"));
- rep->offset = apr_atoi64(str);
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ rep->offset = (apr_off_t)val;
str = apr_strtok(NULL, " ", &last_str);
if (str == NULL)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Malformed text representation offset line in node-rev"));
- rep->size = apr_atoi64(str);
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ rep->size = (svn_filesize_t)val;
str = apr_strtok(NULL, " ", &last_str);
if (str == NULL)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Malformed text representation offset line in node-rev"));
- rep->expanded_size = apr_atoi64(str);
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ rep->expanded_size = (svn_filesize_t)val;
/* Read in the MD5 hash. */
str = apr_strtok(NULL, " ", &last_str);
@@ -2198,7 +2217,10 @@ svn_fs_fs__read_noderev(node_revision_t
/* Read the 'count' field. */
value = apr_hash_get(headers, HEADER_COUNT, APR_HASH_KEY_STRING);
- noderev->predecessor_count = (value == NULL) ? 0 : atoi(value);
+ if (value)
+ SVN_ERR(svn_cstring_atoi(&noderev->predecessor_count, value));
+ else
+ noderev->predecessor_count = 0;
/* Get the properties location. */
value = apr_hash_get(headers, HEADER_PROPS, APR_HASH_KEY_STRING);
@@ -2289,7 +2311,10 @@ svn_fs_fs__read_noderev(node_revision_t
/* Get the mergeinfo count. */
value = apr_hash_get(headers, HEADER_MINFO_CNT, APR_HASH_KEY_STRING);
- noderev->mergeinfo_count = (value == NULL) ? 0 : apr_atoi64(value);
+ if (value)
+ SVN_ERR(svn_cstring_atoi64(&noderev->mergeinfo_count, value));
+ else
+ noderev->mergeinfo_count = 0;
/* Get whether *this* node has mergeinfo. */
value = apr_hash_get(headers, HEADER_MINFO_HERE, APR_HASH_KEY_STRING);
@@ -2476,6 +2501,7 @@ read_rep_line(struct rep_args **rep_args
apr_size_t limit;
struct rep_args *rep_args;
char *str, *last_str;
+ apr_int64_t val;
limit = sizeof(buffer);
SVN_ERR(svn_io_read_length_line(file, buffer, &limit, pool));
@@ -2503,24 +2529,30 @@ read_rep_line(struct rep_args **rep_args
/* We have hopefully a DELTA vs. a non-empty base revision. */
str = apr_strtok(buffer, " ", &last_str);
- if (! str || (strcmp(str, REP_DELTA) != 0)) goto err;
+ if (! str || (strcmp(str, REP_DELTA) != 0))
+ goto error;
str = apr_strtok(NULL, " ", &last_str);
- if (! str) goto err;
+ if (! str)
+ goto error;
rep_args->base_revision = SVN_STR_TO_REV(str);
str = apr_strtok(NULL, " ", &last_str);
- if (! str) goto err;
- rep_args->base_offset = (apr_off_t) apr_atoi64(str);
+ if (! str)
+ goto error;
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ rep_args->base_offset = (apr_off_t)val;
str = apr_strtok(NULL, " ", &last_str);
- if (! str) goto err;
- rep_args->base_length = (apr_size_t) apr_atoi64(str);
+ if (! str)
+ goto error;
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ rep_args->base_length = (apr_size_t)val;
*rep_args_p = rep_args;
return SVN_NO_ERROR;
- err:
+ error:
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Malformed representation header"));
}
@@ -2583,6 +2615,7 @@ get_root_changes_offset(apr_off_t *root_
apr_off_t rev_offset;
char buf[64];
int i, num_bytes;
+ const char *str;
apr_size_t len;
apr_seek_where_t seek_relative;
@@ -2637,7 +2670,8 @@ get_root_changes_offset(apr_off_t *root_
/* Look for the next previous newline. */
for (i = num_bytes - 2; i >= 0; i--)
{
- if (buf[i] == '\n') break;
+ if (buf[i] == '\n')
+ break;
}
if (i < 0)
@@ -2648,24 +2682,42 @@ get_root_changes_offset(apr_off_t *root_
}
i++;
-
- if (root_offset)
- *root_offset = rev_offset + apr_atoi64(&buf[i]);
+ str = &buf[i];
/* find the next space */
for ( ; i < (num_bytes - 2) ; i++)
- if (buf[i] == ' ') break;
+ if (buf[i] == ' ')
+ break;
if (i == (num_bytes - 2))
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Final line in revision file missing space"));
+ if (root_offset)
+ {
+ apr_int64_t val;
+
+ buf[i] = '\0';
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ *root_offset = rev_offset + (apr_off_t)val;
+ }
+
i++;
+ str = &buf[i];
+
+ /* find the next newline */
+ for ( ; i < num_bytes; i++)
+ if (buf[i] == '\n')
+ break;
- /* note that apr_atoi64() will stop reading as soon as it encounters
- the final newline. */
if (changes_offset)
- *changes_offset = rev_offset + apr_atoi64(&buf[i]);
+ {
+ apr_int64_t val;
+
+ buf[i] = '\0';
+ SVN_ERR(svn_cstring_atoi64(&val, str));
+ *changes_offset = rev_offset + (apr_off_t)val;
+ }
return SVN_NO_ERROR;
}
@@ -4676,12 +4728,12 @@ get_txn_proplist(apr_hash_t *proplist,
{
svn_stream_t *stream;
- /* The following error has been observed at least twice in real life when
- * WANdisco software sends a DAV 'MERGE' command to a Subversion server:
- * "Can't open file '[...]/db/transactions/props': No such file or directory"
- * The path should be '[...]/db/transactions/<txn-id>/props'.
- * The only way that could happen is if txn_id was NULL here. */
- SVN_ERR_ASSERT(txn_id != NULL);
+ /* Check for issue #3696. (When we find and fix the cause, we can change
+ * this to an assertion.) */
+ if (txn_id == NULL)
+ return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+ _("Internal error: a null transaction id was "
+ "passed to get_txn_proplist()"));
/* Open the transaction properties file. */
SVN_ERR(svn_stream_open_readonly(&stream, path_txn_props(fs, txn_id, pool),
@@ -7260,7 +7312,7 @@ change_rev_prop_body(void *baton, apr_po
&& !svn_string_compare(wanted_value, present_value)))
{
/* What we expected isn't what we found. */
- return svn_error_createf(SVN_ERR_BAD_PROPERTY_VALUE, NULL,
+ return svn_error_createf(SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, NULL,
_("revprop '%s' has unexpected value in "
"filesystem"),
cb->name);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/id.c Fri Dec 10 21:23:03 2010
@@ -275,6 +275,9 @@ svn_fs_fs__id_parse(const char *data,
if (str[0] == 'r')
{
+ apr_int64_t val;
+ svn_error_t *err;
+
/* This is a revision type ID */
pvt->txn_id = NULL;
@@ -286,7 +289,13 @@ svn_fs_fs__id_parse(const char *data,
str = apr_strtok(NULL, "/", &last_str);
if (str == NULL)
return NULL;
- pvt->offset = apr_atoi64(str);
+ err = svn_cstring_atoi64(&val, str);
+ if (err)
+ {
+ svn_error_clear(err);
+ return NULL;
+ }
+ pvt->offset = (apr_off_t)val;
}
else if (str[0] == 't')
{
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/lock.c Fri Dec 10 21:23:03 2010
@@ -192,7 +192,7 @@ write_digest_file(apr_hash_t *children,
svn_stringbuf_appendbytes(children_list,
svn__apr_hash_index_key(hi),
svn__apr_hash_index_klen(hi));
- svn_stringbuf_appendbytes(children_list, "\n", 1);
+ svn_stringbuf_appendbyte(children_list, '\n');
}
hash_store(hash, CHILDREN_KEY, sizeof(CHILDREN_KEY)-1,
children_list->data, children_list->len, pool);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_fs_fs/structure Fri Dec 10 21:23:03 2010
@@ -102,10 +102,8 @@ When representation sharing is enabled,
representation checksum and location mappings using a SQLite database in
"rep-cache.db". The database has a single table, which stores the sha1
hash text as the primary key, mapped to the representation revision, offset,
-size and expanded size. A final field, reuse count, is currently used
-for distinguishing representations which are shared. This file is not
-required, and may be removed at an abritrary time, with the subsequent
-loss of rep-sharing capabilities.
+size and expanded size. This file is not required, and may be removed at an
+abritrary time, with the subsequent loss of rep-sharing capabilities.
Filesystem formats
------------------
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra/ra_loader.c Fri Dec 10 21:23:03 2010
@@ -641,6 +641,28 @@ svn_error_t *svn_ra_rev_prop(svn_ra_sess
return session->vtable->rev_prop(session, rev, name, value, pool);
}
+struct ccw_baton
+{
+ svn_commit_callback2_t original_callback;
+ void *original_baton;
+
+ svn_ra_session_t *session;
+};
+
+/* Wrapper which populates the repos_root field of the commit_info struct */
+static svn_error_t *
+commit_callback_wrapper(const svn_commit_info_t *commit_info,
+ void *baton,
+ apr_pool_t *pool)
+{
+ struct ccw_baton *ccwb = baton;
+ svn_commit_info_t *ci = svn_commit_info_dup(commit_info, pool);
+
+ SVN_ERR(svn_ra_get_repos_root2(ccwb->session, &ci->repos_root, pool));
+
+ return ccwb->original_callback(ci, ccwb->original_baton, pool);
+}
+
svn_error_t *svn_ra_get_commit_editor3(svn_ra_session_t *session,
const svn_delta_editor_t **editor,
void **edit_baton,
@@ -651,10 +673,21 @@ svn_error_t *svn_ra_get_commit_editor3(s
svn_boolean_t keep_locks,
apr_pool_t *pool)
{
+ /* Allocate this in a pool, since the callback will be called long after
+ this function as returned. */
+ struct ccw_baton *ccwb = apr_palloc(pool, sizeof(*ccwb));
+
+ ccwb->original_callback = callback;
+ ccwb->original_baton = callback_baton;
+ ccwb->session = session;
+
return session->vtable->get_commit_editor(session, editor, edit_baton,
- revprop_table, callback,
- callback_baton, lock_tokens,
- keep_locks, pool);
+ revprop_table,
+ callback
+ ? commit_callback_wrapper
+ : NULL,
+ callback ? ccwb : NULL,
+ lock_tokens, keep_locks, pool);
}
svn_error_t *svn_ra_get_file(svn_ra_session_t *session,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_local/ra_plugin.c Fri Dec 10 21:23:03 2010
@@ -115,12 +115,12 @@ get_username(svn_ra_session_t *session,
if (*sess->username)
{
SVN_ERR(svn_fs_create_access(&access_ctx, sess->username,
- pool));
+ session->pool));
SVN_ERR(svn_fs_set_access(sess->fs, access_ctx));
/* Make sure this context is disassociated when the pool gets
destroyed. */
- apr_pool_cleanup_register(pool, sess->fs, cleanup_access,
+ apr_pool_cleanup_register(session->pool, sess->fs, cleanup_access,
apr_pool_cleanup_null);
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/lock.c Fri Dec 10 21:23:03 2010
@@ -32,6 +32,7 @@
#include "svn_ra.h"
#include "../libsvn_ra/ra_loader.h"
#include "svn_path.h"
+#include "svn_string.h"
#include "svn_time.h"
#include "svn_private_config.h"
@@ -209,8 +210,9 @@ lock_from_baton(svn_lock_t **lock,
{
if (strncmp("Second-", timeout_str, strlen("Second-")) == 0)
{
- int time_offset = atoi(&(timeout_str[7]));
-
+ int time_offset;
+
+ SVN_ERR(svn_cstring_atoi(&time_offset, &(timeout_str[7])));
lck->expiration_date = lck->creation_date
+ apr_time_from_sec(time_offset);
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/options.c Fri Dec 10 21:23:03 2010
@@ -144,6 +144,8 @@ parse_capabilities(ne_request *req,
*youngest_rev = SVN_INVALID_REVNUM;
/* Start out assuming all capabilities are unsupported. */
+ apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+ APR_HASH_KEY_STRING, capability_no);
apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_DEPTH,
APR_HASH_KEY_STRING, capability_no);
apr_hash_set(ras->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/ra_neon.h Fri Dec 10 21:23:03 2010
@@ -57,6 +57,7 @@ extern "C" {
#define SVN_RA_NEON__XML_CDATA (1<<1)
#define SVN_RA_NEON__XML_COLLECT ((1<<2) | SVN_RA_NEON__XML_CDATA)
+/* ### Related to anonymous enum below? */
typedef int svn_ra_neon__xml_elmid;
/** XML element */
@@ -674,7 +675,8 @@ typedef svn_error_t * (*svn_ra_neon__end
* Register a pool cleanup on the pool of REQ to clean up any allocated
* Neon resources.
*
- * ACCPT indicates whether the parser wants read the response body
+ * Return the new parser. Also attach it to REQ if ACCPT is non-null.
+ * ACCPT indicates whether the parser wants to read the response body
* or not. Pass NULL for ACCPT when you don't want the returned parser
* to be attached to REQ.
*/
@@ -739,6 +741,7 @@ svn_ra_neon__check_parse_error(const cha
ne_xml_parser *xml_parser,
const char *url);
+/* ### Related to svn_ra_neon__xml_elmid? */
/* ### add SVN_RA_NEON_ to these to prefix conflicts with (sys) headers? */
enum {
/* Redefine Neon elements */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_neon/util.c Fri Dec 10 21:23:03 2010
@@ -82,6 +82,7 @@ xml_parser_create(svn_ra_neon__request_t
* for our custom error parser - could use the ne_basic.h interfaces.
*/
+/* List of XML elements expected in 207 Multi-Status responses. */
static const svn_ra_neon__xml_elm_t multistatus_elements[] =
{ { "DAV:", "multistatus", ELEM_multistatus, 0 },
{ "DAV:", "response", ELEM_response, 0 },
@@ -99,6 +100,21 @@ static const svn_ra_neon__xml_elm_t mult
};
+/* Sparse matrix listing the permitted child elements of each element.
+
+ The permitted direct children of the element named in the first column are
+ the elements named in the remainder of the row.
+
+ There may be any number of rows, and any number of columns in each row; any
+ non-positive value (such as SVN_RA_NEON__XML_INVALID) serves as a sentinel.
+
+ The last element in a row is returned if the head-of-row element is found
+ with a child that's not listed in the remainder of the row. The singleton
+ element of the last (sentinel) row is returned if a tag-with-children is
+ found that isn't the head of any row.
+
+ See validate_element().
+ */
static const int multistatus_nesting_table[][5] =
{ { ELEM_root, ELEM_multistatus, SVN_RA_NEON__XML_INVALID },
{ ELEM_multistatus, ELEM_response, ELEM_responsedescription,
@@ -115,6 +131,11 @@ static const int multistatus_nesting_tab
};
+/* PARENT and CHILD are enum values of ELEM_* type.
+ Return a positive integer if CHILD is a valid direct child of PARENT, and
+ a negative integer (SVN_RA_NEON__XML_INVALID or SVN_RA_NEON__XML_DECLINE,
+ at the moment) otherwise.
+ */
static int
validate_element(int parent, int child)
{
@@ -148,6 +169,7 @@ typedef struct
svn_boolean_t contains_error;
} multistatus_baton_t;
+/* Implements svn_ra_neon__startelm_cb_t. */
static svn_error_t *
start_207_element(int *elem, void *baton, int parent,
const char *nspace, const char *name, const char **atts)
@@ -193,6 +215,7 @@ start_207_element(int *elem, void *baton
return SVN_NO_ERROR;
}
+/* Implements svn_ra_neon__endelm_cb_t . */
static svn_error_t *
end_207_element(void *baton, int state,
const char *nspace, const char *name)
@@ -269,23 +292,24 @@ end_207_element(void *baton, int state,
}
-static ne_xml_parser *
+/* Create a status parser attached to the request REQ. Detected errors
+ will be returned there. */
+static void
multistatus_parser_create(svn_ra_neon__request_t *req)
{
multistatus_baton_t *b = apr_pcalloc(req->pool, sizeof(*b));
- ne_xml_parser *multistatus_parser =
- svn_ra_neon__xml_parser_create(req, ne_accept_207,
- start_207_element,
- svn_ra_neon__xml_collect_cdata,
- end_207_element, b);
+
+ /* Create a parser, attached to REQ. (Ignore the return value.) */
+ svn_ra_neon__xml_parser_create(req, ne_accept_207,
+ start_207_element,
+ svn_ra_neon__xml_collect_cdata,
+ end_207_element, b);
b->cdata = svn_stringbuf_create("", req->pool);
b->description = svn_stringbuf_create("", req->pool);
b->req = req;
b->propname = svn_stringbuf_create("", req->pool);
b->propstat_description = svn_stringbuf_create("", req->pool);
-
- return multistatus_parser;
}
@@ -403,6 +427,10 @@ compressed_body_reader_cleanup(void *bat
return APR_SUCCESS;
}
+/* Attach READER as a response reader for the request REQ, with the
+ * acceptance function ACCPT. The response body data will be decompressed,
+ * if compressed, before being passed to READER. USERDATA will be passed as
+ * the first argument to the acceptance and reader callbacks. */
static void
attach_ne_body_reader(svn_ra_neon__request_t *req,
ne_accept_response accpt,
@@ -747,7 +775,18 @@ start_err_element(void *baton, int paren
atts);
if (errcode_str && *err)
- (*err)->apr_err = atoi(errcode_str);
+ {
+ apr_int64_t val;
+ svn_error_t *err2;
+
+ err2 = svn_cstring_atoi64(&val, errcode_str);
+ if (err2)
+ {
+ svn_error_clear(err2);
+ break;
+ }
+ (*err)->apr_err = (apr_status_t)val;
+ }
break;
}
@@ -1341,9 +1380,7 @@ svn_ra_neon__simple_request(int *code,
SVN_ERR(svn_ra_neon__request_create(&req, ras, method, url, pool));
- /* we don't need the status parser: it's attached to the request
- and detected errors will be returned there... */
- (void) multistatus_parser_create(req);
+ multistatus_parser_create(req);
/* svn_ra_neon__request_dispatch() adds the custom error response
reader. Neon will take care of the Content-Length calculation */
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/commit.c Fri Dec 10 21:23:03 2010
@@ -1061,6 +1061,18 @@ svndiff_stream_write(void *file_baton,
/* POST against 'me' resource handlers. */
+/* Implements svn_ra_serf__request_body_delegate_t */
+static svn_error_t *
+create_txn_post_body(serf_bucket_t **body_bkt,
+ void *baton,
+ serf_bucket_alloc_t *alloc,
+ apr_pool_t *pool)
+{
+ *body_bkt = SERF_BUCKET_SIMPLE_STRING("( create-txn )", alloc);
+ return SVN_NO_ERROR;
+}
+
+
/* Handler baton for POST request. */
typedef struct
{
@@ -1140,6 +1152,9 @@ open_root(void *edit_baton,
/* Create our activity URL now on the server. */
handler = apr_pcalloc(ctx->pool, sizeof(*handler));
handler->method = "POST";
+ handler->body_type = SVN_SKEL_MIME_TYPE;
+ handler->body_delegate = create_txn_post_body;
+ handler->body_delegate_baton = NULL;
handler->path = ctx->session->me_resource;
handler->conn = ctx->session->conns[0];
handler->session = ctx->session;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/options.c Fri Dec 10 21:23:03 2010
@@ -396,6 +396,8 @@ options_response_handler(serf_request_t
serf_bucket_t *hdrs = serf_bucket_response_get_headers(response);
/* Start out assuming all capabilities are unsupported. */
+ apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_PARTIAL_REPLAY,
+ APR_HASH_KEY_STRING, capability_no);
apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_DEPTH,
APR_HASH_KEY_STRING, capability_no);
apr_hash_set(orc->session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/property.c Fri Dec 10 21:23:03 2010
@@ -162,6 +162,16 @@ svn_ra_serf__get_ver_prop(apr_hash_t *pr
return NULL;
}
+const svn_string_t *
+svn_ra_serf__get_prop_string(apr_hash_t *props,
+ const char *path,
+ const char *ns,
+ const char *name)
+{
+ return svn_ra_serf__get_ver_prop_string(props, path, SVN_INVALID_REVNUM,
+ ns, name);
+}
+
const char *
svn_ra_serf__get_prop(apr_hash_t *props,
const char *path,
@@ -788,7 +798,7 @@ svn_ra_serf__walk_all_props(apr_hash_t *
return SVN_NO_ERROR;
}
-void
+svn_error_t *
svn_ra_serf__walk_all_paths(apr_hash_t *props,
svn_revnum_t rev,
svn_ra_serf__path_rev_walker_t walker,
@@ -802,7 +812,7 @@ svn_ra_serf__walk_all_paths(apr_hash_t *
if (!ver_props)
{
- return;
+ return SVN_NO_ERROR;
}
for (path_hi = apr_hash_first(pool, ver_props); path_hi;
@@ -831,11 +841,13 @@ svn_ra_serf__walk_all_paths(apr_hash_t *
apr_hash_this(name_hi, &prop_name, &prop_len, &prop_val);
/* use a subpool? */
- walker(baton, path_name, path_len, ns_name, ns_len,
- prop_name, prop_len, prop_val, pool);
+ SVN_ERR(walker(baton, path_name, path_len, ns_name, ns_len,
+ prop_name, prop_len, prop_val, pool));
}
}
}
+
+ return SVN_NO_ERROR;
}
static svn_error_t *
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/ra_serf.h Fri Dec 10 21:23:03 2010
@@ -994,7 +994,7 @@ typedef svn_error_t *
const char *name, apr_ssize_t name_len,
const svn_string_t *val,
apr_pool_t *pool);
-void
+svn_error_t *
svn_ra_serf__walk_all_paths(apr_hash_t *props,
svn_revnum_t rev,
svn_ra_serf__path_rev_walker_t walker,
@@ -1033,12 +1033,21 @@ const svn_string_t *
svn_ra_serf__get_ver_prop_string(apr_hash_t *props,
const char *path, svn_revnum_t rev,
const char *ns, const char *name);
+
+/* Wraps svn_ra_serf__get_ver_prop_string(). */
const char *
svn_ra_serf__get_ver_prop(apr_hash_t *props,
const char *path, svn_revnum_t rev,
const char *ns, const char *name);
-/* Same as get_prop, but for the unknown revision */
+/* Same as get_ver_prop_string, but for the unknown revision */
+const svn_string_t *
+svn_ra_serf__get_prop_string(apr_hash_t *props,
+ const char *path,
+ const char *ns,
+ const char *name);
+
+/* Same as get_ver_prop, but for the unknown revision */
const char *
svn_ra_serf__get_prop(apr_hash_t *props,
const char *path,
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/replay.c Fri Dec 10 21:23:03 2010
@@ -90,7 +90,7 @@ typedef struct {
replay_info_t *parent;
} prop_info_t;
-typedef struct {
+typedef struct replay_context_t {
apr_pool_t *src_rev_pool;
apr_pool_t *dst_rev_pool;
@@ -118,6 +118,10 @@ typedef struct {
/* Cached report target url */
const char *report_target;
+ /* Target and revision to fetch revision properties on */
+ const char *revprop_target;
+ svn_revnum_t revprop_rev;
+
/* Revision properties for this revision. */
apr_hash_t *revs_props;
apr_hash_t *props;
@@ -125,6 +129,9 @@ typedef struct {
/* Keep a reference to the XML parser ctx to report any errors. */
svn_ra_serf__xml_parser_t *parser_ctx;
+ /* The propfind for the revision properties of the current revision */
+ svn_ra_serf__propfind_context_t *prop_ctx;
+
} replay_context_t;
@@ -180,11 +187,15 @@ start_replay(svn_ra_serf__xml_parser_t *
{
push_state(parser, ctx, REPORT);
+ /* Before we can continue, we need the revision properties. */
+ SVN_ERR_ASSERT(!ctx->prop_ctx
+ || svn_ra_serf__propfind_is_done(ctx->prop_ctx));
+
/* Create a pool for the commit editor. */
ctx->dst_rev_pool = svn_pool_create(ctx->src_rev_pool);
ctx->props = apr_hash_make(ctx->dst_rev_pool);
- SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->report_target,
- ctx->revision,
+ SVN_ERR(svn_ra_serf__walk_all_props(ctx->revs_props, ctx->revprop_target,
+ ctx->revprop_rev,
svn_ra_serf__set_bare_props,
ctx->props, ctx->dst_rev_pool));
if (ctx->revstart_func)
@@ -751,13 +762,30 @@ svn_ra_serf__replay_range(svn_ra_session
/* Request all properties of a certain revision. */
replay_ctx->report_target = report_target;
replay_ctx->revs_props = apr_hash_make(replay_ctx->src_rev_pool);
+
+ if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
+ {
+ replay_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
+ session->rev_stub, rev);
+ replay_ctx->revprop_rev = SVN_INVALID_REVNUM;
+ }
+ else
+ {
+ replay_ctx->revprop_target = report_target;
+ replay_ctx->revprop_rev = rev;
+ }
+
SVN_ERR(svn_ra_serf__deliver_props(&prop_ctx,
replay_ctx->revs_props, session,
- session->conns[0], report_target,
- rev, "0", all_props,
+ session->conns[0],
+ replay_ctx->revprop_target,
+ replay_ctx->revprop_rev,
+ "0", all_props,
TRUE, NULL,
replay_ctx->src_rev_pool));
+ replay_ctx->prop_ctx = prop_ctx;
+
/* Send the replay report request. */
handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/serf.c Fri Dec 10 21:23:03 2010
@@ -721,7 +721,7 @@ dirent_walker(void *baton,
}
else if (strcmp(name, "getcontentlength") == 0)
{
- entry->size = apr_atoi64(val->data);
+ SVN_ERR(svn_cstring_atoi64(&entry->size, val->data));
}
else if (strcmp(name, "resourcetype") == 0)
{
@@ -907,8 +907,8 @@ svn_ra_serf__get_dir(svn_ra_session_t *r
dirent_walk.base_paths = apr_hash_make(pool);
dirent_walk.orig_path = svn_uri_canonicalize(path, pool);
- svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
- &dirent_walk, pool);
+ SVN_ERR(svn_ra_serf__walk_all_paths(props, revision, path_dirent_walker,
+ &dirent_walk, pool));
*dirents = dirent_walk.base_paths;
}
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_serf/util.c Fri Dec 10 21:23:03 2010
@@ -36,6 +36,7 @@
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_private_config.h"
+#include "svn_string.h"
#include "svn_xml.h"
#include "private/svn_dep_compat.h"
@@ -736,7 +737,10 @@ start_error(svn_ra_serf__xml_parser_t *p
err_code = svn_xml_get_attr_value("errcode", attrs);
if (err_code)
{
- ctx->error->apr_err = apr_atoi64(err_code);
+ apr_int64_t val;
+
+ SVN_ERR(svn_cstring_atoi64(&val, err_code));
+ ctx->error->apr_err = (apr_status_t)val;
}
else
{
@@ -1049,7 +1053,7 @@ svn_ra_serf__handle_multistatus_only(ser
server_err->parser.cdata = cdata_207;
server_err->parser.done = &ctx->done;
server_err->parser.ignore_errors = TRUE;
- }
+ }
else
{
ctx->done = TRUE;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/editorp.c Fri Dec 10 21:23:03 2010
@@ -904,7 +904,9 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
svn_error_clear(editor->abort_edit(edit_baton, subpool));
svn_ra_svn__set_block_handler(conn, blocked_write, &state);
}
- write_err = svn_ra_svn_write_cmd_failure(conn, subpool, err->child);
+ write_err = svn_ra_svn_write_cmd_failure(
+ conn, subpool,
+ svn_ra_svn__locate_real_error_child(err));
if (!write_err)
write_err = svn_ra_svn_flush(conn, subpool);
svn_ra_svn__set_block_handler(conn, NULL, NULL);
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/marshal.c Fri Dec 10 21:23:03 2010
@@ -38,6 +38,7 @@
#include "svn_pools.h"
#include "svn_ra_svn.h"
#include "svn_private_config.h"
+#include "svn_ctype.h"
#include "ra_svn.h"
@@ -593,7 +594,7 @@ static svn_error_t *read_item(svn_ra_svn
/* Determine the item type and read it in. Make sure that c is the
* first character at the end of the item so we can test to make
* sure it's whitespace. */
- if (apr_isdigit(c))
+ if (svn_ctype_isdigit(c))
{
/* It's a number or a string. Read the number part, either way. */
val = c - '0';
@@ -601,7 +602,7 @@ static svn_error_t *read_item(svn_ra_svn
{
prev_val = val;
SVN_ERR(readbuf_getchar(conn, pool, &c));
- if (!apr_isdigit(c))
+ if (!svn_ctype_isdigit(c))
break;
val = val * 10 + (c - '0');
if ((val / 10) != prev_val) /* val wrapped past maximum value */
@@ -621,16 +622,16 @@ static svn_error_t *read_item(svn_ra_svn
item->u.number = val;
}
}
- else if (apr_isalpha(c))
+ else if (svn_ctype_isalpha(c))
{
/* It's a word. */
str = svn_stringbuf_ncreate(&c, 1, pool);
while (1)
{
SVN_ERR(readbuf_getchar(conn, pool, &c));
- if (!apr_isalnum(c) && c != '-')
+ if (!svn_ctype_isalnum(c) && c != '-')
break;
- svn_stringbuf_appendbytes(str, &c, 1);
+ svn_stringbuf_appendbyte(str, c);
}
item->kind = SVN_RA_SVN_WORD;
item->u.word = str->data;
@@ -831,6 +832,21 @@ svn_error_t *svn_ra_svn_parse_proplist(c
/* --- READING AND WRITING COMMANDS AND RESPONSES --- */
+svn_error_t *svn_ra_svn__locate_real_error_child(svn_error_t *err)
+{
+ svn_error_t *this_link;
+
+ SVN_ERR_ASSERT(err);
+
+ for (this_link = err;
+ this_link && (this_link->apr_err == SVN_ERR_RA_SVN_CMD_ERR);
+ this_link = this_link->child)
+ ;
+
+ SVN_ERR_ASSERT(this_link);
+ return this_link;
+}
+
svn_error_t *svn_ra_svn__handle_failure_status(const apr_array_header_t *params,
apr_pool_t *pool)
{
@@ -859,12 +875,27 @@ svn_error_t *svn_ra_svn__handle_failure_
easily change that, so "" means a nonexistent message. */
if (!*message)
message = NULL;
- err = svn_error_create((apr_status_t)apr_err, err, message);
- err->file = apr_pstrdup(err->pool, file);
- err->line = (long)line;
+
+ /* Skip over links in the error chain that were intended only to
+ exist on the server (to wrap real errors intended for the
+ client) but accidentally got included in the server's actual
+ response. */
+ if ((apr_status_t)apr_err != SVN_ERR_RA_SVN_CMD_ERR)
+ {
+ err = svn_error_create((apr_status_t)apr_err, err, message);
+ err->file = apr_pstrdup(err->pool, file);
+ err->line = (long)line;
+ }
}
svn_pool_destroy(subpool);
+
+ /* If we get here, then we failed to find a real error in the error
+ chain that the server proported to be sending us. That's bad. */
+ if (! err)
+ err = svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ _("Malformed error list"));
+
return err;
}
@@ -940,7 +971,9 @@ svn_error_t *svn_ra_svn_handle_commands2
if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
{
- write_err = svn_ra_svn_write_cmd_failure(conn, iterpool, err->child);
+ write_err = svn_ra_svn_write_cmd_failure(
+ conn, iterpool,
+ svn_ra_svn__locate_real_error_child(err));
svn_error_clear(err);
if (write_err)
return write_err;
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_ra_svn/ra_svn.h Fri Dec 10 21:23:03 2010
@@ -122,6 +122,11 @@ svn_error_t *svn_ra_svn__cram_client(svn
const char *user, const char *password,
const char **message);
+/* Return a pointer to the error chain child of ERR which contains the
+ * first "real" error message, not merely one of the
+ * SVN_ERR_RA_SVN_CMD_ERR wrapper errors. */
+svn_error_t *svn_ra_svn__locate_real_error_child(svn_error_t *err);
+
/* Return an error chain based on @a params (which contains a
* command response indicating failure). The error chain will be
* in the same order as the errors indicated in @a params. Use
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/dump.c Fri Dec 10 21:23:03 2010
@@ -42,6 +42,7 @@
/*----------------------------------------------------------------------*/
+
/* Compute the delta between OLDROOT/OLDPATH and NEWROOT/NEWPATH and
store it into a new temporary file *TEMPFILE. OLDROOT may be NULL,
in which case the delta will be computed against an empty file, as
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/load.c Fri Dec 10 21:23:03 2010
@@ -34,9 +34,11 @@
#include "svn_mergeinfo.h"
#include "svn_checksum.h"
#include "svn_subst.h"
+#include "svn_ctype.h"
#include <apr_lib.h>
+#include "private/svn_dep_compat.h"
#include "private/svn_mergeinfo_private.h"
/*----------------------------------------------------------------------*/
@@ -449,9 +451,11 @@ parse_property_block(svn_stream_t *strea
else if ((buf[0] == 'K') && (buf[1] == ' '))
{
char *keybuf;
+ apr_uint64_t len;
+ SVN_ERR(svn_cstring_strtoui64(&len, buf + 2, 0, APR_SIZE_MAX, 10));
SVN_ERR(read_key_or_val(&keybuf, actual_length,
- stream, atoi(buf + 2), proppool));
+ stream, (apr_size_t)len, proppool));
/* Read a val length line */
SVN_ERR(svn_stream_readline(stream, &strbuf, "\n", &eof, proppool));
@@ -465,8 +469,10 @@ parse_property_block(svn_stream_t *strea
{
svn_string_t propstring;
char *valbuf;
+ apr_int64_t val;
- propstring.len = atoi(buf + 2);
+ SVN_ERR(svn_cstring_atoi64(&val, buf + 2));
+ propstring.len = (apr_size_t)val;
SVN_ERR(read_key_or_val(&valbuf, actual_length,
stream, propstring.len, proppool));
propstring.data = valbuf;
@@ -523,9 +529,11 @@ parse_property_block(svn_stream_t *strea
else if ((buf[0] == 'D') && (buf[1] == ' '))
{
char *keybuf;
+ apr_uint64_t len;
+ SVN_ERR(svn_cstring_strtoui64(&len, buf + 2, 0, APR_SIZE_MAX, 10));
SVN_ERR(read_key_or_val(&keybuf, actual_length,
- stream, atoi(buf + 2), proppool));
+ stream, (apr_size_t)len, proppool));
/* We don't expect these in revision properties, and if we see
one when we don't have a delete_node_property callback,
@@ -642,7 +650,7 @@ parse_format_version(const char *version
return svn_error_create(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
_("Malformed dumpfile header"));
- value = atoi(p+1);
+ SVN_ERR(svn_cstring_atoi(&value, p + 1));
if (value > SVN_REPOS_DUMPFILE_FORMAT_VERSION)
return svn_error_createf(SVN_ERR_STREAM_MALFORMED_DATA, NULL,
@@ -735,7 +743,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
return stream_ran_dry();
}
- if ((linebuf->len == 0) || (apr_isspace(linebuf->data[0])))
+ if ((linebuf->len == 0) || (svn_ctype_isspace(linebuf->data[0])))
continue; /* empty line ... loop */
/*** Found the beginning of a new record. ***/
@@ -784,7 +792,7 @@ svn_repos_parse_dumpstream2(svn_stream_t
APR_HASH_KEY_STRING)))
{
/* ### someday, switch modes of operation here. */
- version = atoi(value);
+ SVN_ERR(svn_cstring_atoi(&version, value));
}
/* Or is this bogosity?! */
else
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_repos/reporter.c Fri Dec 10 21:23:03 2010
@@ -32,6 +32,7 @@
#include "svn_props.h"
#include "repos.h"
#include "svn_private_config.h"
+#include "private/svn_dep_compat.h"
#define NUM_CACHED_SOURCE_ROOTS 4
@@ -155,11 +156,6 @@ read_number(apr_uint64_t *num, apr_file_
return SVN_NO_ERROR;
}
-#ifndef APR_SIZE_MAX
-/* APR 0.9 doesn't define APR_SIZE_MAX */
-#define APR_SIZE_MAX (~((apr_size_t)0))
-#endif
-
static svn_error_t *
read_string(const char **str, apr_file_t *temp, apr_pool_t *pool)
{
Modified: subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c?rev=1044516&r1=1044515&r2=1044516&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/ignore-mergeinfo/subversion/libsvn_subr/config_file.c Fri Dec 10 21:23:03 2010
@@ -34,6 +34,7 @@
#include "svn_utf.h"
#include "svn_pools.h"
#include "svn_user.h"
+#include "svn_ctype.h"
#include "svn_private_config.h"
@@ -121,7 +122,7 @@ skip_whitespace(parse_context_t *ctx, in
int count = 0;
SVN_ERR(parser_getc(ctx, &ch));
- while (ch != EOF && ch != '\n' && apr_isspace(ch))
+ while (ch != EOF && ch != '\n' && svn_ctype_isspace(ch))
{
++count;
SVN_ERR(parser_getc(ctx, &ch));
@@ -162,7 +163,7 @@ parse_value(int *pch, parse_context_t *c
/* last ch seen was ':' or '=' in parse_option. */
{
const char char_from_int = ch;
- svn_stringbuf_appendbytes(ctx->value, &char_from_int, 1);
+ svn_stringbuf_appendbyte(ctx->value, char_from_int);
SVN_ERR(parser_getc(ctx, &ch));
}
/* Leading and trailing whitespace is ignored. */
@@ -213,13 +214,12 @@ parse_value(int *pch, parse_context_t *c
else
{
/* This is a continuation line. Read it. */
- svn_stringbuf_appendbytes(ctx->value, " ", 1);
+ svn_stringbuf_appendbyte(ctx->value, ' ');
while (ch != EOF && ch != '\n')
{
const char char_from_int = ch;
- svn_stringbuf_appendbytes(ctx->value,
- &char_from_int, 1);
+ svn_stringbuf_appendbyte(ctx->value, char_from_int);
SVN_ERR(parser_getc(ctx, &ch));
}
/* Trailing whitespace is ignored. */
@@ -246,7 +246,7 @@ parse_option(int *pch, parse_context_t *
while (ch != EOF && ch != ':' && ch != '=' && ch != '\n')
{
const char char_from_int = ch;
- svn_stringbuf_appendbytes(ctx->option, &char_from_int, 1);
+ svn_stringbuf_appendbyte(ctx->option, char_from_int);
SVN_ERR(parser_getc(ctx, &ch));
}
@@ -289,7 +289,7 @@ parse_section_name(int *pch, parse_conte
while (ch != EOF && ch != ']' && ch != '\n')
{
const char char_from_int = ch;
- svn_stringbuf_appendbytes(ctx->section, &char_from_int, 1);
+ svn_stringbuf_appendbyte(ctx->section, char_from_int);
SVN_ERR(parser_getc(ctx, &ch));
}