Browse Source

fix all analysis warnings.

null-safety
Herbert Poul 4 years ago
parent
commit
f43110ee52
  1. 2
      bin/kdbx.dart
  2. 92
      example/pubspec.lock
  3. 2
      example/pubspec.yaml
  4. 6
      lib/src/crypto/key_encrypter_kdf.dart
  5. 4
      lib/src/internal/async_utils.dart
  6. 1
      lib/src/internal/crypto_utils.dart
  7. 4
      lib/src/kdbx_binary.dart
  8. 2
      lib/src/kdbx_custom_data.dart
  9. 5
      lib/src/kdbx_dao.dart
  10. 4
      lib/src/kdbx_entry.dart
  11. 15
      lib/src/kdbx_format.dart
  12. 2
      lib/src/kdbx_group.dart
  13. 11
      lib/src/kdbx_header.dart
  14. 20
      lib/src/kdbx_meta.dart
  15. 6
      lib/src/kdbx_object.dart
  16. 3
      lib/src/kdbx_times.dart
  17. 3
      lib/src/kdbx_var_dictionary.dart
  18. 17
      lib/src/kdbx_xml.dart
  19. 3
      lib/src/utils/byte_utils.dart
  20. 3
      test/kdbx_test.dart
  21. 1
      test/kdbx_upgrade_test.dart
  22. 2
      test/var_dictionary_test.dart

2
bin/kdbx.dart

@ -5,8 +5,6 @@ import 'package:argon2_ffi_base/argon2_ffi_base.dart';
import 'package:args/args.dart'; import 'package:args/args.dart';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/crypto/protected_value.dart';
import 'package:kdbx/src/kdbx_format.dart';
import 'package:kdbx/src/utils/print_utils.dart'; import 'package:kdbx/src/utils/print_utils.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:logging_appenders/logging_appenders.dart'; import 'package:logging_appenders/logging_appenders.dart';

92
example/pubspec.lock

@ -7,14 +7,14 @@ packages:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.13" version: "3.1.2"
argon2_ffi_base: argon2_ffi_base:
dependency: transitive dependency: transitive
description: description:
name: argon2_ffi_base name: argon2_ffi_base
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4+6" version: "1.0.0+2"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -28,21 +28,21 @@ packages:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.3" version: "1.2.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.13" version: "1.15.0"
convert: convert:
dependency: transitive dependency: transitive
description: description:
@ -56,77 +56,63 @@ packages:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.5" version: "3.0.1"
cryptography:
dependency: transitive
description:
name: cryptography
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
dio: dio:
dependency: transitive dependency: transitive
description: description:
name: dio name: dio
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.10" version: "4.0.0"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
name: ffi name: ffi
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.3" version: "1.0.0"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.4" version: "4.0.0"
intl: intl:
dependency: transitive dependency: transitive
description: description:
name: intl name: intl
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.17.0"
io: isolates:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
isolate:
dependency: transitive dependency: transitive
description: description:
name: isolate name: isolates
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "3.0.3+8"
kdbx: kdbx:
dependency: "direct main" dependency: "direct main"
description: description:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.4.1" version: "1.0.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:
name: logging name: logging
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.11.4" version: "1.0.1"
logging_appenders: logging_appenders:
dependency: transitive dependency: transitive
description: description:
name: logging_appenders name: logging_appenders
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.2+5" version: "1.0.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -140,14 +126,14 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.2" version: "1.3.0"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
pedantic: pedantic:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -168,14 +154,7 @@ packages:
name: pointycastle name: pointycastle
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "3.0.1"
prompts:
dependency: transitive
description:
name: prompts
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
@ -183,20 +162,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "2.1.3"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.24.1"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -210,28 +182,42 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.1.0"
supercharged_dart:
dependency: transitive
description:
name: supercharged_dart
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "3.0.4"
xml: xml:
dependency: transitive dependency: transitive
description: description:
@ -240,4 +226,4 @@ packages:
source: hosted source: hosted
version: "4.4.1" version: "4.4.1"
sdks: sdks:
dart: ">=2.8.0 <3.0.0" dart: ">=2.12.0 <3.0.0"

2
example/pubspec.yaml

@ -12,4 +12,4 @@ dependencies:
path: ../ path: ../
dev_dependencies: dev_dependencies:
pedantic: ^1.9.2 pedantic: '>=1.7.0 <2.0.0'

6
lib/src/crypto/key_encrypter_kdf.dart

@ -5,8 +5,8 @@ import 'package:argon2_ffi_base/argon2_ffi_base.dart';
import 'package:crypto/crypto.dart' as crypto; import 'package:crypto/crypto.dart' as crypto;
import 'package:isolates/isolate_runner.dart'; import 'package:isolates/isolate_runner.dart';
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:kdbx/src/kdbx_var_dictionary.dart'; import 'package:kdbx/src/kdbx_var_dictionary.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:pointycastle/export.dart'; import 'package:pointycastle/export.dart';
@ -98,12 +98,12 @@ class KeyEncrypterKdf {
case KdfType.Argon2: case KdfType.Argon2:
_logger.fine('Must be using argon2'); _logger.fine('Must be using argon2');
return await encryptArgon2(key, kdfParameters); return await encryptArgon2(key, kdfParameters);
break;
case KdfType.Aes: case KdfType.Aes:
_logger.fine('Must be using aes'); _logger.fine('Must be using aes');
return await encryptAes(key, kdfParameters); return await encryptAes(key, kdfParameters);
default:
throw UnsupportedError('unsupported KDF Type $kdfType.');
} }
throw UnsupportedError('unsupported KDF Type $kdfType.');
} }
Future<Uint8List> encryptArgon2( Future<Uint8List> encryptArgon2(

4
lib/src/internal/async_utils.dart

@ -9,9 +9,7 @@ mixin StreamSubscriberBase {
/// Listens to a stream and saves it to the list of subscriptions. /// Listens to a stream and saves it to the list of subscriptions.
void listen(Stream<dynamic> stream, void Function(dynamic data) onData, void listen(Stream<dynamic> stream, void Function(dynamic data) onData,
{Function? onError}) { {Function? onError}) {
if (stream != null) { _subscriptions.add(stream.listen(onData, onError: onError));
_subscriptions.add(stream.listen(onData, onError: onError));
}
} }
void handle(StreamSubscription<dynamic> subscription) { void handle(StreamSubscription<dynamic> subscription) {

1
lib/src/internal/crypto_utils.dart

@ -49,7 +49,6 @@ class AesHelper {
break; break;
default: default:
throw ArgumentError('incorrect value of the "mode" parameter'); throw ArgumentError('incorrect value of the "mode" parameter');
break;
} }
cipher.init(false, params); cipher.init(false, params);

4
lib/src/kdbx_binary.dart

@ -2,10 +2,9 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:kdbx/src/kdbx_header.dart'; import 'package:kdbx/src/kdbx_header.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:meta/meta.dart'; import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:quiver/core.dart'; import 'package:quiver/core.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
@ -43,7 +42,6 @@ class KdbxBinary {
static KdbxBinary readBinaryXml(XmlElement valueNode, static KdbxBinary readBinaryXml(XmlElement valueNode,
{required bool isInline}) { {required bool isInline}) {
assert(isInline != null);
final isProtected = valueNode.getAttributeBool(KdbxXml.ATTR_PROTECTED); final isProtected = valueNode.getAttributeBool(KdbxXml.ATTR_PROTECTED);
final isCompressed = valueNode.getAttributeBool(KdbxXml.ATTR_COMPRESSED); final isCompressed = valueNode.getAttributeBool(KdbxXml.ATTR_COMPRESSED);
var value = base64.decode(valueNode.text.trim()); var value = base64.decode(valueNode.text.trim());

2
lib/src/kdbx_custom_data.dart

@ -1,7 +1,7 @@
import 'package:kdbx/src/internal/extension_utils.dart';
import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_object.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:xml/xml.dart' as xml; import 'package:xml/xml.dart' as xml;
import 'package:kdbx/src/internal/extension_utils.dart';
class KdbxCustomData extends KdbxNode { class KdbxCustomData extends KdbxNode {
KdbxCustomData.create() KdbxCustomData.create()

5
lib/src/kdbx_dao.dart

@ -2,7 +2,6 @@ import 'package:kdbx/src/kdbx_entry.dart';
import 'package:kdbx/src/kdbx_file.dart'; import 'package:kdbx/src/kdbx_file.dart';
import 'package:kdbx/src/kdbx_group.dart'; import 'package:kdbx/src/kdbx_group.dart';
import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_object.dart';
import 'package:meta/meta.dart';
/// Helper object for accessing and modifing data inside /// Helper object for accessing and modifing data inside
/// a kdbx file. /// a kdbx file.
@ -11,7 +10,6 @@ extension KdbxDao on KdbxFile {
required KdbxGroup parent, required KdbxGroup parent,
required String name, required String name,
}) { }) {
assert(parent != null, name != null);
final newGroup = KdbxGroup.create(ctx: ctx, parent: parent, name: name); final newGroup = KdbxGroup.create(ctx: ctx, parent: parent, name: name);
parent.addGroup(newGroup); parent.addGroup(newGroup);
return newGroup; return newGroup;
@ -20,7 +18,7 @@ extension KdbxDao on KdbxFile {
KdbxGroup findGroupByUuid(KdbxUuid? uuid) => KdbxGroup findGroupByUuid(KdbxUuid? uuid) =>
body.rootGroup.getAllGroups().firstWhere((group) => group.uuid == uuid, body.rootGroup.getAllGroups().firstWhere((group) => group.uuid == uuid,
orElse: (() => orElse: (() =>
throw StateError('Unable to find group with uuid $uuid')) as KdbxGroup Function()?); throw StateError('Unable to find group with uuid $uuid')));
void deleteGroup(KdbxGroup group) { void deleteGroup(KdbxGroup group) {
move(group, getRecycleBinOrCreate()); move(group, getRecycleBinOrCreate());
@ -31,7 +29,6 @@ extension KdbxDao on KdbxFile {
} }
void move(KdbxObject kdbxObject, KdbxGroup toGroup) { void move(KdbxObject kdbxObject, KdbxGroup toGroup) {
assert(toGroup != null);
kdbxObject.times.locationChanged.setToNow(); kdbxObject.times.locationChanged.setToNow();
if (kdbxObject is KdbxGroup) { if (kdbxObject is KdbxGroup) {
kdbxObject.parent!.internalRemoveGroup(kdbxObject); kdbxObject.parent!.internalRemoveGroup(kdbxObject);

4
lib/src/kdbx_entry.dart

@ -296,7 +296,6 @@ class KdbxEntry extends KdbxObject {
StringValue? getString(KdbxKey key) => _strings[key]; StringValue? getString(KdbxKey key) => _strings[key];
void setString(KdbxKey key, StringValue? value) { void setString(KdbxKey key, StringValue? value) {
assert(key != null);
if (_strings[key] == value) { if (_strings[key] == value) {
_logger.finest('Value did not change for $key'); _logger.finest('Value did not change for $key');
return; return;
@ -338,9 +337,6 @@ class KdbxEntry extends KdbxObject {
required String name, required String name,
required Uint8List bytes, required Uint8List bytes,
}) { }) {
assert(isProtected != null);
assert(bytes != null);
assert(name != null);
// make sure we don't have a path, just the file name. // make sure we don't have a path, just the file name.
final key = _uniqueBinaryName(path.basename(name)); final key = _uniqueBinaryName(path.basename(name));
final binary = KdbxBinary( final binary = KdbxBinary(

15
lib/src/kdbx_format.dart

@ -11,18 +11,12 @@ import 'package:crypto/crypto.dart' as crypto;
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/crypto/key_encrypter_kdf.dart'; import 'package:kdbx/src/crypto/key_encrypter_kdf.dart';
import 'package:kdbx/src/crypto/protected_salt_generator.dart'; import 'package:kdbx/src/crypto/protected_salt_generator.dart';
import 'package:kdbx/src/crypto/protected_value.dart';
import 'package:kdbx/src/internal/consts.dart'; import 'package:kdbx/src/internal/consts.dart';
import 'package:kdbx/src/internal/crypto_utils.dart'; import 'package:kdbx/src/internal/crypto_utils.dart';
import 'package:kdbx/src/internal/extension_utils.dart'; import 'package:kdbx/src/internal/extension_utils.dart';
import 'package:kdbx/src/kdbx_binary.dart';
import 'package:kdbx/src/kdbx_deleted_object.dart'; import 'package:kdbx/src/kdbx_deleted_object.dart';
import 'package:kdbx/src/kdbx_entry.dart'; import 'package:kdbx/src/kdbx_entry.dart';
import 'package:kdbx/src/kdbx_file.dart';
import 'package:kdbx/src/kdbx_group.dart';
import 'package:kdbx/src/kdbx_header.dart'; import 'package:kdbx/src/kdbx_header.dart';
import 'package:kdbx/src/kdbx_meta.dart';
import 'package:kdbx/src/kdbx_object.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:kdbx/src/utils/byte_utils.dart'; import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
@ -39,7 +33,7 @@ abstract class Credentials {
Credentials.composite(password, null); //PasswordCredentials(password); Credentials.composite(password, null); //PasswordCredentials(password);
factory Credentials.composite(ProtectedValue password, Uint8List? keyFile) => factory Credentials.composite(ProtectedValue password, Uint8List? keyFile) =>
KeyFileComposite( KeyFileComposite(
password: password == null ? null : PasswordCredentials(password), password: PasswordCredentials(password),
keyFile: keyFile == null ? null : KeyFileCredentials(keyFile), keyFile: keyFile == null ? null : KeyFileCredentials(keyFile),
); );
@ -73,9 +67,7 @@ class KdbxReadWriteContext {
KdbxReadWriteContext({ KdbxReadWriteContext({
required List<KdbxBinary> binaries, required List<KdbxBinary> binaries,
required this.header, required this.header,
}) : assert(binaries != null), }) : _binaries = binaries,
assert(header != null),
_binaries = binaries,
_deletedObjects = []; _deletedObjects = [];
static final kdbxContext = Expando<KdbxReadWriteContext>(); static final kdbxContext = Expando<KdbxReadWriteContext>();
@ -129,7 +121,6 @@ class KdbxReadWriteContext {
/// finds the ID of the given binary. /// finds the ID of the given binary.
/// if it can't be found, [KdbxCorruptedFileException] is thrown. /// if it can't be found, [KdbxCorruptedFileException] is thrown.
int findBinaryId(KdbxBinary binary) { int findBinaryId(KdbxBinary binary) {
assert(binary != null);
assert(!binary.isInline!); assert(!binary.isInline!);
final id = _binaries.indexOf(binary); final id = _binaries.indexOf(binary);
if (id < 0) { if (id < 0) {
@ -818,7 +809,7 @@ class KdbxFormat {
final deletedObjects = root final deletedObjects = root
.findElements(KdbxXml.NODE_DELETED_OBJECTS) .findElements(KdbxXml.NODE_DELETED_OBJECTS)
.singleOrNull .singleOrNull
?.let((el) => el! ?.let((el) => el
.findElements(KdbxDeletedObject.NODE_NAME) .findElements(KdbxDeletedObject.NODE_NAME)
.map((node) => KdbxDeletedObject.read(node, ctx))) ?? .map((node) => KdbxDeletedObject.read(node, ctx))) ??
[]; [];

2
lib/src/kdbx_group.dart

@ -1,11 +1,9 @@
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/internal/extension_utils.dart'; import 'package:kdbx/src/internal/extension_utils.dart';
import 'package:kdbx/src/kdbx_consts.dart';
import 'package:kdbx/src/kdbx_entry.dart'; import 'package:kdbx/src/kdbx_entry.dart';
import 'package:kdbx/src/kdbx_format.dart'; import 'package:kdbx/src/kdbx_format.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import 'kdbx_object.dart'; import 'kdbx_object.dart';

11
lib/src/kdbx_header.dart

@ -2,12 +2,11 @@ import 'dart:typed_data';
import 'package:crypto/crypto.dart' as crypto; import 'package:crypto/crypto.dart' as crypto;
import 'package:kdbx/src/crypto/key_encrypter_kdf.dart'; import 'package:kdbx/src/crypto/key_encrypter_kdf.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:kdbx/src/internal/consts.dart'; import 'package:kdbx/src/internal/consts.dart';
import 'package:kdbx/src/kdbx_binary.dart'; import 'package:kdbx/src/kdbx_binary.dart';
import 'package:kdbx/src/kdbx_var_dictionary.dart'; import 'package:kdbx/src/kdbx_var_dictionary.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:quiver/check.dart'; import 'package:quiver/check.dart';
import 'package:quiver/core.dart'; import 'package:quiver/core.dart';
@ -482,7 +481,8 @@ class KdbxHeader {
return Cipher.aes; return Cipher.aes;
} }
try { try {
return CryptoConsts.cipherFromBytes(fields[HeaderFields.CipherID]!.bytes!); return CryptoConsts.cipherFromBytes(
fields[HeaderFields.CipherID]!.bytes!);
} catch (e, stackTrace) { } catch (e, stackTrace) {
_logger.warning( _logger.warning(
'Unable to find cipher. ' 'Unable to find cipher. '
@ -509,7 +509,7 @@ class KdbxHeader {
final id = final id =
ReaderHelper.singleUint32(fields[HeaderFields.CompressionFlags]!.bytes); ReaderHelper.singleUint32(fields[HeaderFields.CompressionFlags]!.bytes);
return _compressionIdsById[id] ?? return _compressionIdsById[id] ??
(() => throw KdbxUnsupportedException('invalid compression $id'))()!; (() => throw KdbxUnsupportedException('invalid compression $id'))();
} }
ProtectedValueEncryption get innerRandomStreamEncryption => ProtectedValueEncryption get innerRandomStreamEncryption =>
@ -638,8 +638,7 @@ class InnerHeader {
InnerHeader({ InnerHeader({
required this.fields, required this.fields,
List<InnerHeaderField>? binaries, List<InnerHeaderField>? binaries,
}) : binaries = binaries ?? [], }) : binaries = binaries ?? [];
assert(fields != null);
factory InnerHeader.fromFields(Iterable<InnerHeaderField> fields) { factory InnerHeader.fromFields(Iterable<InnerHeaderField> fields) {
final fieldMap = Map.fromEntries(fields final fieldMap = Map.fromEntries(fields

20
lib/src/kdbx_meta.dart

@ -9,13 +9,11 @@ import 'package:kdbx/src/kdbx_format.dart';
import 'package:kdbx/src/kdbx_header.dart'; import 'package:kdbx/src/kdbx_header.dart';
import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_object.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:meta/meta.dart'; import 'package:logging/logging.dart';
import 'package:quiver/iterables.dart'; import 'package:quiver/iterables.dart';
import 'package:xml/xml.dart' as xml; import 'package:xml/xml.dart' as xml;
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import 'package:logging/logging.dart';
final _logger = Logger('kdbx_meta'); final _logger = Logger('kdbx_meta');
class KdbxMeta extends KdbxNode implements KdbxNodeContext { class KdbxMeta extends KdbxNode implements KdbxNodeContext {
@ -41,12 +39,12 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext {
KdbxMeta.read(xml.XmlElement node, this.ctx) KdbxMeta.read(xml.XmlElement node, this.ctx)
: customData = node : customData = node
.singleElement('CustomData') .singleElement('CustomData')
?.let((e) => KdbxCustomData.read(e!)) ?? ?.let((e) => KdbxCustomData.read(e)) ??
KdbxCustomData.create(), KdbxCustomData.create(),
binaries = node binaries = node
.singleElement(KdbxXml.NODE_BINARIES) .singleElement(KdbxXml.NODE_BINARIES)
?.let((el) sync* { ?.let((el) sync* {
for (final binaryNode in el!.findElements(KdbxXml.NODE_BINARY)) { for (final binaryNode in el.findElements(KdbxXml.NODE_BINARY)) {
final id = int.parse(binaryNode.getAttribute(KdbxXml.ATTR_ID)!); final id = int.parse(binaryNode.getAttribute(KdbxXml.ATTR_ID)!);
yield MapEntry( yield MapEntry(
id, id,
@ -54,9 +52,9 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext {
); );
} }
}) })
?.toList() .toList()
?.let((binaries) { .let((binaries) {
binaries!.sort((a, b) => a.key.compareTo(b.key)); binaries.sort((a, b) => a.key.compareTo(b.key));
for (var i = 0; i < binaries.length; i++) { for (var i = 0; i < binaries.length; i++) {
if (i != binaries[i].key) { if (i != binaries[i].key) {
throw KdbxCorruptedFileException( throw KdbxCorruptedFileException(
@ -69,7 +67,7 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext {
_customIcons = node _customIcons = node
.singleElement(KdbxXml.NODE_CUSTOM_ICONS) .singleElement(KdbxXml.NODE_CUSTOM_ICONS)
?.let((el) sync* { ?.let((el) sync* {
for (final iconNode in el!.findElements(KdbxXml.NODE_ICON)) { for (final iconNode in el.findElements(KdbxXml.NODE_ICON)) {
yield KdbxCustomIcon( yield KdbxCustomIcon(
uuid: KdbxUuid( uuid: KdbxUuid(
iconNode.singleTextNode(KdbxXml.NODE_UUID)), iconNode.singleTextNode(KdbxXml.NODE_UUID)),
@ -77,8 +75,8 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext {
iconNode.singleTextNode(KdbxXml.NODE_DATA))); iconNode.singleTextNode(KdbxXml.NODE_DATA)));
} }
}) })
?.map((e) => MapEntry(e.uuid, e)) .map((e) => MapEntry(e.uuid, e))
?.let((that) => Map.fromEntries(that!)) ?? .let((that) => Map.fromEntries(that)) ??
{}, {},
super.read(node); super.read(node);

6
lib/src/kdbx_object.dart

@ -151,16 +151,14 @@ abstract class KdbxObject extends KdbxNode {
this.file, this.file,
String nodeName, String nodeName,
KdbxGroup? parent, KdbxGroup? parent,
) : assert(ctx != null), ) : times = KdbxTimes.create(ctx),
times = KdbxTimes.create(ctx),
_parent = parent, _parent = parent,
super.create(nodeName) { super.create(nodeName) {
_uuid.set(KdbxUuid.random()); _uuid.set(KdbxUuid.random());
} }
KdbxObject.read(this.ctx, KdbxGroup? parent, XmlElement node) KdbxObject.read(this.ctx, KdbxGroup? parent, XmlElement node)
: assert(ctx != null), : times = KdbxTimes.read(node.findElements('Times').single, ctx),
times = KdbxTimes.read(node.findElements('Times').single, ctx),
_parent = parent, _parent = parent,
super.read(node); super.read(node);

3
lib/src/kdbx_times.dart

@ -2,11 +2,10 @@ import 'package:clock/clock.dart';
import 'package:kdbx/src/kdbx_format.dart'; import 'package:kdbx/src/kdbx_format.dart';
import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_object.dart';
import 'package:kdbx/src/kdbx_xml.dart'; import 'package:kdbx/src/kdbx_xml.dart';
import 'package:logging/logging.dart';
import 'package:quiver/iterables.dart'; import 'package:quiver/iterables.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import 'package:logging/logging.dart';
final _logger = Logger('kdbx_times'); final _logger = Logger('kdbx_times');
class KdbxTimes extends KdbxNode implements KdbxNodeContext { class KdbxTimes extends KdbxNode implements KdbxNodeContext {

3
lib/src/kdbx_var_dictionary.dart

@ -88,8 +88,7 @@ class VarDictionaryItem<T> {
class VarDictionary { class VarDictionary {
VarDictionary(List<VarDictionaryItem<dynamic>> items) VarDictionary(List<VarDictionaryItem<dynamic>> items)
: assert(items != null), : _items = items,
_items = items,
_dict = Map.fromEntries(items.map((item) => MapEntry(item._key, item))); _dict = Map.fromEntries(items.map((item) => MapEntry(item._key, item)));
factory VarDictionary.read(ReaderHelper reader) { factory VarDictionary.read(ReaderHelper reader) {

17
lib/src/kdbx_xml.dart

@ -3,16 +3,15 @@ import 'dart:typed_data';
import 'package:clock/clock.dart'; import 'package:clock/clock.dart';
import 'package:collection/collection.dart' show IterableExtension; import 'package:collection/collection.dart' show IterableExtension;
import 'package:kdbx/src/kdbx_consts.dart';
import 'package:kdbx/src/kdbx_format.dart'; import 'package:kdbx/src/kdbx_format.dart';
import 'package:kdbx/src/kdbx_header.dart'; import 'package:kdbx/src/kdbx_header.dart';
import 'package:kdbx/src/kdbx_object.dart'; import 'package:kdbx/src/kdbx_object.dart';
import 'package:kdbx/src/utils/byte_utils.dart'; import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:kdbx/src/kdbx_consts.dart'; import 'package:logging/logging.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import 'package:logging/logging.dart';
final _logger = Logger('kdbx_xml'); final _logger = Logger('kdbx_xml');
class KdbxXml { class KdbxXml {
@ -92,9 +91,8 @@ abstract class KdbxSubTextNode<T> extends KdbxSubNode<T?> {
@protected @protected
T decode(String value); T decode(String value);
XmlElement? _opt(String nodeName) => node.node XmlElement? _opt(String nodeName) =>
.findElements(nodeName) node.node.findElements(nodeName).singleWhereOrNull((x) => true);
.singleWhereOrNull((x) => true);
void setOnModifyListener(void Function() onModify) { void setOnModifyListener(void Function() onModify) {
_onModify = onModify; _onModify = onModify;
@ -192,7 +190,7 @@ class IconNode extends KdbxSubTextNode<KdbxIcon> {
} }
class KdbxColor { class KdbxColor {
const KdbxColor._fromRgbCode(this._rgb) : assert(_rgb != null && _rgb != ''); const KdbxColor._fromRgbCode(this._rgb) : assert(_rgb != '');
const KdbxColor._nullColor() : _rgb = ''; const KdbxColor._nullColor() : _rgb = '';
factory KdbxColor.parse(String rgb) => factory KdbxColor.parse(String rgb) =>
@ -220,7 +218,7 @@ class BooleanNode extends KdbxSubTextNode<bool?> {
@override @override
bool? decode(String value) { bool? decode(String value) {
switch (value?.toLowerCase()) { switch (value.toLowerCase()) {
case 'null': case 'null':
return null; return null;
case 'true': case 'true':
@ -252,9 +250,6 @@ class DateTimeUtcNode extends KdbxSubTextNode<DateTime?> {
@override @override
DateTime? decode(String value) { DateTime? decode(String value) {
if (value == null) {
return null;
}
if (value.isEmpty) { if (value.isEmpty) {
_logger.warning('time contains empty string. $name'); _logger.warning('time contains empty string. $name');
return null; return null;

3
lib/src/utils/byte_utils.dart

@ -1,5 +1,4 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
@ -32,7 +31,7 @@ class ByteUtils {
static String toHex(int val) => '0x${val.toRadixString(16).padLeft(2, '0')}'; static String toHex(int val) => '0x${val.toRadixString(16).padLeft(2, '0')}';
static String toHexList(List<int>? list) => static String toHexList(List<int>? list) =>
list?.map((val) => toHex(val))?.join(' ') ?? '(null)'; list?.map((val) => toHex(val)).join(' ') ?? '(null)';
} }
extension Uint8ListExt on Uint8List { extension Uint8ListExt on Uint8List {

3
test/kdbx_test.dart

@ -1,12 +1,9 @@
@Tags(['kdbx3']) @Tags(['kdbx3'])
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/crypto/protected_salt_generator.dart'; import 'package:kdbx/src/crypto/protected_salt_generator.dart';
import 'package:kdbx/src/crypto/protected_value.dart';
import 'package:kdbx/src/kdbx_format.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:logging_appenders/logging_appenders.dart'; import 'package:logging_appenders/logging_appenders.dart';
import 'package:synchronized/synchronized.dart'; import 'package:synchronized/synchronized.dart';

1
test/kdbx_upgrade_test.dart

@ -1,7 +1,6 @@
@Tags(['kdbx3', 'kdbx4']) @Tags(['kdbx3', 'kdbx4'])
import 'package:kdbx/kdbx.dart'; import 'package:kdbx/kdbx.dart';
import 'package:kdbx/src/kdbx_header.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'internal/test_utils.dart'; import 'internal/test_utils.dart';

2
test/var_dictionary_test.dart

@ -1,6 +1,6 @@
import 'package:kdbx/src/crypto/key_encrypter_kdf.dart'; import 'package:kdbx/src/crypto/key_encrypter_kdf.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:kdbx/src/kdbx_var_dictionary.dart'; import 'package:kdbx/src/kdbx_var_dictionary.dart';
import 'package:kdbx/src/utils/byte_utils.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:logging_appenders/logging_appenders.dart'; import 'package:logging_appenders/logging_appenders.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';

Loading…
Cancel
Save