summaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_fs/verify.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
committerPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
commit3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch)
tree7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_fs_fs/verify.c
parenta55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff)
Notes
Diffstat (limited to 'subversion/libsvn_fs_fs/verify.c')
-rw-r--r--subversion/libsvn_fs_fs/verify.c53
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));