Browse Source

keepassxc compatibility - accept kdbx 3 binaries in arbitrary sort order.

pull/3/head
Herbert Poul 5 years ago
parent
commit
bb6560b1b8
  1. 2
      lib/src/kdbx_entry.dart
  2. 35
      lib/src/kdbx_meta.dart
  3. 12
      test/kdbx_binaries_test.dart
  4. BIN
      test/test_files/binarytest-keepassxc.kdbx

2
lib/src/kdbx_entry.dart

@ -286,6 +286,8 @@ class KdbxEntry extends KdbxObject {
Iterable<MapEntry<KdbxKey, KdbxBinary>> get binaryEntries =>
_binaries.entries;
KdbxBinary getBinary(KdbxKey key) => _binaries[key];
// Map<KdbxKey, StringValue> get strings => UnmodifiableMapView(_strings);
Iterable<MapEntry<KdbxKey, StringValue>> get stringEntries =>

35
lib/src/kdbx_meta.dart

@ -43,18 +43,29 @@ class KdbxMeta extends KdbxNode implements KdbxNodeContext {
.singleElement('CustomData')
?.let((e) => KdbxCustomData.read(e)) ??
KdbxCustomData.create(),
binaries = node.singleElement(KdbxXml.NODE_BINARIES)?.let((el) sync* {
var i = 0;
for (final binaryNode in el.findElements(KdbxXml.NODE_BINARY)) {
final id = int.parse(binaryNode.getAttribute(KdbxXml.ATTR_ID));
if (id != i) {
throw KdbxCorruptedFileException(
'Invalid ID for binary. expected $i, but was $id');
}
i++;
yield KdbxBinary.readBinaryXml(binaryNode, isInline: false);
}
})?.toList(),
binaries = node
.singleElement(KdbxXml.NODE_BINARIES)
?.let((el) sync* {
for (final binaryNode in el.findElements(KdbxXml.NODE_BINARY)) {
final id = int.parse(binaryNode.getAttribute(KdbxXml.ATTR_ID));
yield MapEntry(
id,
KdbxBinary.readBinaryXml(binaryNode, isInline: false),
);
}
})
?.toList()
?.let((binaries) {
binaries.sort((a, b) => a.key.compareTo(b.key));
for (var i = 0; i < binaries.length; i++) {
if (i != binaries[i].key) {
throw KdbxCorruptedFileException(
'Invalid ID for binary. expected $i,'
' but was ${binaries[i].key}');
}
}
return binaries.map((e) => e.value).toList();
}),
_customIcons = node
.singleElement(KdbxXml.NODE_CUSTOM_ICONS)
?.let((el) sync* {

12
test/kdbx_binaries_test.dart

@ -122,6 +122,18 @@ void main() {
// make sure the file can still be saved.
await file.save();
});
test('keepassxc compatibility', () async {
// keepass has files in arbitrary sort order.
final file = await TestUtil.readKdbxFile(
'test/test_files/binarytest-keepassxc.kdbx');
final entry = file.body.rootGroup.entries.first;
for (final name in ['a', 'b', 'c', 'd', 'e']) {
expect(
utf8.decode(entry.getBinary(KdbxKey('$name.txt')).value).trim(),
name,
);
}
});
}, tags: ['kdbx3']);
group('kdbx4 attachment', () {
test('read binary', () async {

BIN
test/test_files/binarytest-keepassxc.kdbx

Binary file not shown.
Loading…
Cancel
Save