diff options
Diffstat (limited to 'subversion/libsvn_fs_fs/verify.c')
-rw-r--r-- | subversion/libsvn_fs_fs/verify.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/subversion/libsvn_fs_fs/verify.c b/subversion/libsvn_fs_fs/verify.c index 0fa314bfddf45..7fe5ecbbd4941 100644 --- a/subversion/libsvn_fs_fs/verify.c +++ b/subversion/libsvn_fs_fs/verify.c @@ -30,6 +30,7 @@ #include "cached_data.h" #include "rep-cache.h" +#include "revprops.h" #include "util.h" #include "index.h" @@ -463,7 +464,8 @@ expect_buffer_nul(apr_file_t *file, /* read the whole data block; error out on failure */ data.chunks[(size - 1)/ sizeof(apr_uint64_t)] = 0; - SVN_ERR(svn_io_file_read_full2(file, data.buffer, size, NULL, NULL, pool)); + SVN_ERR(svn_io_file_read_full2(file, data.buffer, (apr_size_t)size, NULL, + NULL, pool)); /* chunky check */ for (i = 0; i < size / sizeof(apr_uint64_t); ++i) @@ -478,7 +480,7 @@ expect_buffer_nul(apr_file_t *file, apr_off_t offset; SVN_ERR(svn_io_file_name_get(&file_name, file, pool)); - SVN_ERR(svn_fs_fs__get_file_offset(&offset, file, pool)); + SVN_ERR(svn_io_file_get_offset(&offset, file, pool)); offset -= size - i; return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, @@ -671,15 +673,45 @@ compare_p2l_to_rev(svn_fs_t *fs, apr_off_t_toa(pool, offset), apr_off_t_toa(pool, entry->offset)); - /* empty sections must contain NUL bytes only */ + /* Check type <-> item dependencies. */ + + /* Entry types must be within the valid range. */ + if (entry->type >= SVN_FS_FS__ITEM_TYPE_ANY_REP) + return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, + NULL, + _("p2l index entry for revision r%ld" + " at offset %s contains invalid item" + " type %d"), + start, + apr_off_t_toa(pool, offset), + entry->type); + + /* There can be only one changes entry and that has a fixed type + * and item number. Its presence and parse-ability will be checked + * during later stages of the verification process. */ + if ( (entry->type == SVN_FS_FS__ITEM_TYPE_CHANGES) + != (entry->item.number == SVN_FS_FS__ITEM_INDEX_CHANGES)) + return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, + NULL, + _("p2l index entry for changes in" + " revision r%ld is item %ld of type" + " %d at offset %s"), + entry->item.revision, + entry->item.number, + entry->type, + apr_off_t_toa(pool, offset)); + + /* Check contents. */ if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED) { - /* skip filler entry at the end of the p2l index */ + /* Empty sections must contain NUL bytes only. + * Beware of the filler at the end of the p2l index. */ if (entry->offset != max_offset) SVN_ERR(read_all_nul(rev_file->file, entry->size, pool)); } else { + /* Generic contents check against checksum. */ if (entry->size < STREAM_THRESHOLD) SVN_ERR(expected_buffered_checksum(rev_file->file, entry, pool)); @@ -720,6 +752,10 @@ verify_revprops(svn_fs_t *fs, svn_revnum_t revision; apr_pool_t *iterpool = svn_pool_create(pool); + /* Invalidate the revprop cache once. + * Use the cache inside the loop to speed up packed revprop access. */ + svn_fs_fs__reset_revprop_cache(fs); + for (revision = start; revision < end; ++revision) { svn_string_t *date; @@ -730,7 +766,8 @@ verify_revprops(svn_fs_t *fs, /* Access the svn:date revprop. * This implies parsing all revprops for that revision. */ SVN_ERR(svn_fs_fs__revision_prop(&date, fs, revision, - SVN_PROP_REVISION_DATE, iterpool)); + SVN_PROP_REVISION_DATE, FALSE, + iterpool, iterpool)); /* The time stamp is the only revprop that, if given, needs to * have a valid content. */ @@ -857,13 +894,15 @@ svn_fs_fs__verify(svn_fs_t *fs, apr_pool_t *pool) { fs_fs_data_t *ffd = fs->fsap_data; - svn_revnum_t youngest = ffd->youngest_rev_cache; /* cache is current */ /* Input validation. */ if (! SVN_IS_VALID_REVNUM(start)) start = 0; if (! SVN_IS_VALID_REVNUM(end)) - end = youngest; + { + SVN_ERR(svn_fs_fs__youngest_rev(&end, fs, pool)); + } + SVN_ERR(svn_fs_fs__ensure_revision_exists(start, fs, pool)); SVN_ERR(svn_fs_fs__ensure_revision_exists(end, fs, pool)); |