From 463d8010fb51344fabf78f1c914bd8cc21ea8f68 Mon Sep 17 00:00:00 2001 From: maRci002 Date: Wed, 23 Feb 2022 14:58:52 +0100 Subject: [PATCH 1/2] Sync position of writeRaf during recovery --- hive/lib/src/backend/vm/storage_backend_vm.dart | 1 + hive/test/tests/backend/vm/storage_backend_vm_test.dart | 3 +++ 2 files changed, 4 insertions(+) diff --git a/hive/lib/src/backend/vm/storage_backend_vm.dart b/hive/lib/src/backend/vm/storage_backend_vm.dart index 341017799..79879f6af 100644 --- a/hive/lib/src/backend/vm/storage_backend_vm.dart +++ b/hive/lib/src/backend/vm/storage_backend_vm.dart @@ -92,6 +92,7 @@ class StorageBackendVm extends StorageBackend { if (_crashRecovery) { print('Recovering corrupted box.'); await writeRaf.truncate(recoveryOffset); + await writeRaf.setPosition(recoveryOffset); writeOffset = recoveryOffset; } else { throw HiveError('Wrong checksum in hive file. Box may be corrupted.'); diff --git a/hive/test/tests/backend/vm/storage_backend_vm_test.dart b/hive/test/tests/backend/vm/storage_backend_vm_test.dart index ae9e93a4a..8ca1e4607 100644 --- a/hive/test/tests/backend/vm/storage_backend_vm_test.dart +++ b/hive/test/tests/backend/vm/storage_backend_vm_test.dart @@ -169,10 +169,13 @@ void main() { when(() => lockRaf.lock()).thenAnswer((i) => Future.value(lockRaf)); when(() => writeRaf.truncate(20)) .thenAnswer((i) => Future.value(writeRaf)); + when(() => writeRaf.setPosition(20)) + .thenAnswer((i) => Future.value(writeRaf)); await backend.initialize( TypeRegistryImpl.nullImpl, MockKeystore(), lazy); verify(() => writeRaf.truncate(20)); + verify(() => writeRaf.setPosition(20)); }); test('recoveryOffset without crash recovery', () async { From 284c83bf1f353a049b6dd630a9efaf65f834fab3 Mon Sep 17 00:00:00 2001 From: maRci002 Date: Wed, 23 Feb 2022 16:35:46 +0100 Subject: [PATCH 2/2] BinaryReader.readFrame return null when frameLength < 8 --- hive/lib/src/binary/binary_reader_impl.dart | 10 +++--- .../test/tests/binary/binary_reader_test.dart | 35 ++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/hive/lib/src/binary/binary_reader_impl.dart b/hive/lib/src/binary/binary_reader_impl.dart index 163cdd527..cc3d0d5d4 100644 --- a/hive/lib/src/binary/binary_reader_impl.dart +++ b/hive/lib/src/binary/binary_reader_impl.dart @@ -243,13 +243,14 @@ class BinaryReaderImpl extends BinaryReader { /// Not part of public API Frame? readFrame( {HiveCipher? cipher, bool lazy = false, int frameOffset = 0}) { + // frame length is stored on 4 bytes if (availableBytes < 4) return null; + // frame length should be at least 8 bytes var frameLength = readUint32(); - if (frameLength < 8) { - throw HiveError( - 'This should not happen. Please open an issue on GitHub.'); - } + if (frameLength < 8) return null; + + // frame is bigger than avaible bytes if (availableBytes < frameLength - 4) return null; var crc = _buffer.readUint32(_offset + frameLength - 8); @@ -260,6 +261,7 @@ class BinaryReaderImpl extends BinaryReader { crc: cipher?.calculateKeyCrc() ?? 0, ); + // frame is corrupted or provided chiper is different if (computedCrc != crc) return null; _limitAvailableBytes(frameLength - 8); diff --git a/hive/test/tests/binary/binary_reader_test.dart b/hive/test/tests/binary/binary_reader_test.dart index 6f0b1aa09..2c028ff58 100644 --- a/hive/test/tests/binary/binary_reader_test.dart +++ b/hive/test/tests/binary/binary_reader_test.dart @@ -351,6 +351,39 @@ void main() { }); group('.readFrame()', () { + final List nullFramesBytes = [ + // availableBytes < 4 + // there is ONLY 3 bytes provided + Uint8List.fromList([8, 0, 0]), + // frameLength < 8 + // frame is 7 length + Uint8List.fromList([7, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + // availableBytes < frameLength - 4 + // frame is 10 length however ONLY 9 bytes provided + Uint8List.fromList([10, 0, 0, 0, 0, 0, 0, 0, 0]), + // computedCrc != crc + // 0, 0, 0, 0 crc is: 0 and computedCrc is: 274301637 + Uint8List.fromList([10, 0, 0, 0, 0, 0, 0, 0, 0, 0]), + ]; + + test('null', () { + for (final bytes in nullFramesBytes) { + final reader = BinaryReaderImpl(bytes, testRegistry); + final frame = reader.readFrame(lazy: false); + + expect(frame, null); + } + }); + + test('null lazy', () { + for (final bytes in nullFramesBytes) { + final reader = BinaryReaderImpl(bytes, testRegistry); + final frame = reader.readFrame(lazy: true); + + expect(frame, null); + } + }); + test('normal', () { var frames = framesSetLengthOffset(testFrames, frameBytes); var offset = 0; @@ -397,7 +430,7 @@ void main() { } }); - test('lazy', () { + test('encrypted lazy', () { var frames = framesSetLengthOffset(testFrames, frameBytesEncrypted); var offset = 0; for (var i = 0; i < frames.length; i++) {