X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Ftransaction.c;h=73ceb9620265ee70b86320871c57aba0488c429f;hb=ba7740e689b5791d79b95d2c5345870f9c29fb71;hp=7a2ebbe9a3bb111e0a2c7ea2c4573a6ac2f82b44;hpb=1fa54dfd198611a15f4c701a0525ea4ac2af4343;p=ccan diff --git a/ccan/tdb2/transaction.c b/ccan/tdb2/transaction.c index 7a2ebbe9..73ceb962 100644 --- a/ccan/tdb2/transaction.c +++ b/ccan/tdb2/transaction.c @@ -815,6 +815,7 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb, if (offset >= old_map_size) { continue; } + if (offset + length > tdb->file->map_size) { free(data); return tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, @@ -829,9 +830,19 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb, /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ - ecode = methods->tread(tdb, offset, - p + sizeof(offset) + sizeof(length), - length); + if (offset + length > old_map_size) { + /* Short read at EOF, and zero fill. */ + unsigned int len = old_map_size - offset; + ecode = methods->tread(tdb, offset, + p + sizeof(offset) + sizeof(length), + len); + memset(p + sizeof(offset) + sizeof(length) + len, 0, + length - len); + } else { + ecode = methods->tread(tdb, offset, + p + sizeof(offset) + sizeof(length), + length); + } if (ecode != TDB_SUCCESS) { free(data); return ecode;