mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-21 21:57:36 +00:00
cache sync: add more refcount tests
This commit is contained in:
parent
4faaa7d1fa
commit
5af66dbb12
2 changed files with 65 additions and 2 deletions
|
@ -251,8 +251,12 @@ static inline int unpack_callback_array_end(unpack_user* u)
|
||||||
/* b'chunks': [ ( b'1234...', 123, 345 )
|
/* b'chunks': [ ( b'1234...', 123, 345 )
|
||||||
* ^ */
|
* ^ */
|
||||||
cache_entry = (uint32_t*) hashindex_get(u->chunks, u->current.key);
|
cache_entry = (uint32_t*) hashindex_get(u->chunks, u->current.key);
|
||||||
if (cache_entry) {
|
if(cache_entry) {
|
||||||
refcount = _le32toh(cache_entry[0]);
|
refcount = _le32toh(cache_entry[0]);
|
||||||
|
if(refcount > _MAX_VALUE) {
|
||||||
|
SET_LAST_ERROR("invalid reference count");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
refcount += 1;
|
refcount += 1;
|
||||||
cache_entry[0] = _htole32(MIN(refcount, _MAX_VALUE));
|
cache_entry[0] = _htole32(MIN(refcount, _MAX_VALUE));
|
||||||
} else {
|
} else {
|
||||||
|
@ -260,7 +264,7 @@ static inline int unpack_callback_array_end(unpack_user* u)
|
||||||
cache_values[0] = _htole32(1);
|
cache_values[0] = _htole32(1);
|
||||||
cache_values[1] = _htole32(u->current.size);
|
cache_values[1] = _htole32(u->current.size);
|
||||||
cache_values[2] = _htole32(u->current.csize);
|
cache_values[2] = _htole32(u->current.csize);
|
||||||
if (!hashindex_set(u->chunks, u->current.key, cache_values)) {
|
if(!hashindex_set(u->chunks, u->current.key, cache_values)) {
|
||||||
SET_LAST_ERROR("hashindex_set failed");
|
SET_LAST_ERROR("hashindex_set failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import io
|
||||||
|
|
||||||
from msgpack import packb
|
from msgpack import packb
|
||||||
|
|
||||||
|
@ -137,3 +138,61 @@ def test_corrupted_ancillary(self, index, sync, data, error):
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
sync.feed(packed)
|
sync.feed(packed)
|
||||||
assert str(excinfo.value) == 'cache_sync_feed failed: ' + error
|
assert str(excinfo.value) == 'cache_sync_feed failed: ' + error
|
||||||
|
|
||||||
|
def make_index_with_refcount(self, refcount):
|
||||||
|
index_data = io.BytesIO()
|
||||||
|
index_data.write(b'BORG_IDX')
|
||||||
|
# num_entries
|
||||||
|
index_data.write((1).to_bytes(4, 'little'))
|
||||||
|
# num_buckets
|
||||||
|
index_data.write((1).to_bytes(4, 'little'))
|
||||||
|
# key_size
|
||||||
|
index_data.write((32).to_bytes(1, 'little'))
|
||||||
|
# value_size
|
||||||
|
index_data.write((3 * 4).to_bytes(1, 'little'))
|
||||||
|
|
||||||
|
index_data.write(H(0))
|
||||||
|
index_data.write(refcount.to_bytes(4, 'little'))
|
||||||
|
index_data.write((1234).to_bytes(4, 'little'))
|
||||||
|
index_data.write((5678).to_bytes(4, 'little'))
|
||||||
|
|
||||||
|
index_data.seek(0)
|
||||||
|
index = ChunkIndex.read(index_data)
|
||||||
|
return index
|
||||||
|
|
||||||
|
def test_corrupted_refcount(self):
|
||||||
|
index = self.make_index_with_refcount(ChunkIndex.MAX_VALUE + 1)
|
||||||
|
sync = CacheSynchronizer(index)
|
||||||
|
data = packb({
|
||||||
|
'chunks': [
|
||||||
|
(H(0), 1, 2),
|
||||||
|
]
|
||||||
|
})
|
||||||
|
with pytest.raises(ValueError) as excinfo:
|
||||||
|
sync.feed(data)
|
||||||
|
assert str(excinfo.value) == 'cache_sync_feed failed: invalid reference count'
|
||||||
|
|
||||||
|
def test_refcount_max_value(self):
|
||||||
|
index = self.make_index_with_refcount(ChunkIndex.MAX_VALUE)
|
||||||
|
sync = CacheSynchronizer(index)
|
||||||
|
data = packb({
|
||||||
|
'chunks': [
|
||||||
|
(H(0), 1, 2),
|
||||||
|
]
|
||||||
|
})
|
||||||
|
sync.feed(data)
|
||||||
|
assert index[H(0)] == (ChunkIndex.MAX_VALUE, 1234, 5678)
|
||||||
|
|
||||||
|
def test_refcount_one_below_max_value(self):
|
||||||
|
index = self.make_index_with_refcount(ChunkIndex.MAX_VALUE - 1)
|
||||||
|
sync = CacheSynchronizer(index)
|
||||||
|
data = packb({
|
||||||
|
'chunks': [
|
||||||
|
(H(0), 1, 2),
|
||||||
|
]
|
||||||
|
})
|
||||||
|
sync.feed(data)
|
||||||
|
# Incremented to maximum
|
||||||
|
assert index[H(0)] == (ChunkIndex.MAX_VALUE, 1234, 5678)
|
||||||
|
sync.feed(data)
|
||||||
|
assert index[H(0)] == (ChunkIndex.MAX_VALUE, 1234, 5678)
|
||||||
|
|
Loading…
Reference in a new issue