You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/02/11 23:35:59 UTC
svn commit: r1444985 - /subversion/trunk/subversion/libsvn_wc/diff_editor.c
Author: rhuijben
Date: Mon Feb 11 22:35:58 2013
New Revision: 1444985
URL: http://svn.apache.org/r1444985
Log:
In the repos-wc diff handling: verify the expected checksum and simplify
some base handling in close_file.
* subversion/libsvn_wc/diff_editor.c
(file_baton_t): Add base props and the raw checksum data.
(open_file): Obtain the base-props.
(window_handler_baton): Remove struct.
(window_handler): Remove function.
(apply_textdelta): Verify expected checksum. Directly hook libsvn_delta's
window handler as the stream wrappers can do all our work.
(close_file): Parse result hash here. Use base checksum as cached.
Modified:
subversion/trunk/subversion/libsvn_wc/diff_editor.c
Modified: subversion/trunk/subversion/libsvn_wc/diff_editor.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/diff_editor.c?rev=1444985&r1=1444984&r2=1444985&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/diff_editor.c (original)
+++ subversion/trunk/subversion/libsvn_wc/diff_editor.c Mon Feb 11 22:35:58 2013
@@ -344,11 +344,12 @@ struct file_baton_t
/* Has a change on regular properties */
svn_boolean_t has_propchange;
- /* The current checksum on disk */
+ /* The current BASE checksum and props */
const svn_checksum_t *base_checksum;
+ apr_hash_t *base_props;
/* The resulting checksum from apply_textdelta */
- svn_checksum_t *result_checksum;
+ unsigned char result_digest[APR_MD5_DIGESTSIZE];
/* The overall crawler editor baton. */
struct edit_baton_t *eb;
@@ -1692,7 +1693,7 @@ open_file(const char *path,
SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, &fb->base_checksum, NULL,
- NULL, NULL, NULL, NULL,
+ NULL, NULL, &fb->base_props, NULL,
eb->db, fb->local_abspath,
fb->pool, fb->pool));
@@ -1711,56 +1712,63 @@ open_file(const char *path,
return SVN_NO_ERROR;
}
-/* Baton for window_handler */
-struct window_handler_baton
-{
- struct file_baton_t *fb;
-
- /* APPLY_HANDLER/APPLY_BATON represent the delta applcation baton. */
- svn_txdelta_window_handler_t apply_handler;
- void *apply_baton;
-
- unsigned char result_digest[APR_MD5_DIGESTSIZE];
-};
-
-/* Do the work of applying the text delta. */
-static svn_error_t *
-window_handler(svn_txdelta_window_t *window,
- void *window_baton)
-{
- struct window_handler_baton *whb = window_baton;
- struct file_baton_t *fb = whb->fb;
-
- SVN_ERR(whb->apply_handler(window, whb->apply_baton));
-
- if (!window)
- {
- fb->result_checksum = svn_checksum__from_digest_md5(whb->result_digest,
- fb->pool);
- }
-
- return SVN_NO_ERROR;
-}
-
/* An svn_delta_editor_t function. */
static svn_error_t *
apply_textdelta(void *file_baton,
- const char *base_checksum,
+ const char *base_checksum_hex,
apr_pool_t *pool,
svn_txdelta_window_handler_t *handler,
void **handler_baton)
{
struct file_baton_t *fb = file_baton;
- struct window_handler_baton *whb;
struct edit_baton_t *eb = fb->eb;
svn_stream_t *source;
svn_stream_t *temp_stream;
+ svn_checksum_t *repos_checksum = NULL;
- if (fb->base_checksum)
- SVN_ERR(svn_wc__db_pristine_read(&source, NULL,
- eb->db, fb->local_abspath,
- fb->base_checksum,
- pool, pool));
+ if (base_checksum_hex && fb->base_checksum)
+ {
+ const svn_checksum_t *base_md5;
+ SVN_ERR(svn_checksum_parse_hex(&repos_checksum, svn_checksum_md5,
+ base_checksum_hex, pool));
+
+ SVN_ERR(svn_wc__db_pristine_get_md5(&base_md5,
+ eb->db, eb->anchor_abspath,
+ fb->base_checksum,
+ pool, pool));
+
+ if (! svn_checksum_match(repos_checksum, base_md5))
+ {
+ /* ### I expect that there are some bad drivers out there
+ ### that used to give bad results. We could look in
+ ### working to see if the expected checksum matches and
+ ### then return the pristine of that... But that only moves
+ ### the problem */
+
+ /* If needed: compare checksum obtained via md5 of working.
+ And if they match set fb->base_checksum and fb->base_props */
+
+ return svn_checksum_mismatch_err(
+ base_md5,
+ repos_checksum,
+ pool,
+ _("Checksum mismatch for '%s'"),
+ svn_dirent_local_style(fb->local_abspath,
+ pool));
+ }
+
+ SVN_ERR(svn_wc__db_pristine_read(&source, NULL,
+ eb->db, fb->local_abspath,
+ fb->base_checksum,
+ pool, pool));
+ }
+ else if (fb->base_checksum)
+ {
+ SVN_ERR(svn_wc__db_pristine_read(&source, NULL,
+ eb->db, fb->local_abspath,
+ fb->base_checksum,
+ pool, pool));
+ }
else
source = svn_stream_empty(pool);
@@ -1769,17 +1777,12 @@ apply_textdelta(void *file_baton,
svn_io_file_del_on_pool_cleanup,
fb->pool, fb->pool));
- whb = apr_pcalloc(fb->pool, sizeof(*whb));
- whb->fb = fb;
-
svn_txdelta_apply(source, temp_stream,
- whb->result_digest,
+ fb->result_digest,
fb->path /* error_info */,
fb->pool,
- &whb->apply_handler, &whb->apply_baton);
+ handler, handler_baton);
- *handler = window_handler;
- *handler_baton = whb;
return SVN_NO_ERROR;
}
@@ -1805,7 +1808,6 @@ close_file(void *file_baton,
svn_error_t *err;
/* The BASE information */
- const svn_checksum_t *pristine_checksum;
const char *pristine_file;
apr_hash_t *pristine_props;
@@ -1824,7 +1826,9 @@ close_file(void *file_baton,
if (expected_md5_digest != NULL)
{
svn_checksum_t *expected_checksum;
- const svn_checksum_t *repos_checksum = fb->result_checksum;
+ const svn_checksum_t *repos_checksum = svn_checksum__from_digest_md5(
+ fb->result_digest,
+ scratch_pool);
SVN_ERR(svn_checksum_parse_hex(&expected_checksum, svn_checksum_md5,
expected_md5_digest, scratch_pool));
@@ -1856,7 +1860,7 @@ close_file(void *file_baton,
}
err = svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, &pristine_checksum, NULL,
+ NULL, NULL, NULL, NULL, NULL,
&original_repos_relpath,
NULL, NULL, &original_revision, NULL, NULL, NULL,
NULL, NULL, NULL, &had_props, &props_mod,
@@ -1868,7 +1872,6 @@ close_file(void *file_baton,
{
svn_error_clear(err);
status = svn_wc__db_status_not_present;
- pristine_checksum = NULL;
had_props = FALSE;
props_mod = FALSE;
original_repos_relpath = NULL;
@@ -1884,25 +1887,13 @@ close_file(void *file_baton,
}
else
{
- if (status != svn_wc__db_status_normal)
- SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- &pristine_checksum,
- NULL, NULL,
- &had_props, NULL, NULL,
- db, fb->local_abspath,
- scratch_pool, scratch_pool));
-
SVN_ERR(svn_wc__db_pristine_get_path(&pristine_file,
db, fb->local_abspath,
- pristine_checksum,
+ fb->base_checksum,
scratch_pool, scratch_pool));
- if (had_props)
- SVN_ERR(svn_wc__db_base_get_props(&pristine_props,
- db, fb->local_abspath,
- scratch_pool, scratch_pool));
- else
+ pristine_props = fb->base_props;
+ if (! pristine_props)
pristine_props = apr_hash_make(scratch_pool);
}