use Encode qw(encode);
use File::KDBX::Constants qw(:version :time);
use File::KDBX::Error;
-use File::KDBX::Util qw(assert_64bit erase_scoped gzip snakify);
+use File::KDBX::Util qw(:class assert_64bit erase_scoped gzip snakify);
use IO::Handle;
-use Scalar::Util qw(isdual looks_like_number);
+use Scalar::Util qw(blessed isdual looks_like_number);
use Time::Piece;
use XML::LibXML;
use boolean;
use namespace::clean;
-use parent 'File::KDBX::Dumper';
+extends 'File::KDBX::Dumper';
our $VERSION = '999.999'; # VERSION
Get whether or not protected strings and binaries should be written in an encrypted stream. Default: C<TRUE>
-=cut
-
-sub allow_protection {
- my $self = shift;
- $self->{allow_protection} = shift if @_;
- $self->{allow_protection} //= 1;
-}
-
=attr binaries
$bool = $dumper->binaries;
Get whether or not binaries within the database should be written. Default: C<TRUE>
-=cut
-
-sub binaries {
- my $self = shift;
- $self->{binaries} = shift if @_;
- $self->{binaries} //= $self->kdbx->version < KDBX_VERSION_4_0;
-}
-
=attr compress_binaries
$tristate = $dumper->compress_binaries;
* C<FALSE> - Never compress binaries
* C<undef> - Compress binaries if it results in smaller database sizes (default)
-=cut
-
-sub compress_binaries {
- my $self = shift;
- $self->{compress_binaries} = shift if @_;
- $self->{compress_binaries};
-}
-
=attr compress_datetimes
$bool = $dumper->compress_datetimes;
bytes. The default is to write compressed datetimes if the KDBX file version is 4+, otherwise use the
human-readable format.
-=cut
-
-sub compress_datetimes {
- my $self = shift;
- $self->{compress_datetimes} = shift if @_;
- $self->{compress_datetimes};
-}
-
=attr header_hash
$octets = $dumper->header_hash;
format uses HMAC-SHA256 to detect tampering.
L<File::KDBX::Dumper::V3> automatically calculates the header hash an provides it to this module, and plain
-XML files which don't have a KDBX wrapper don't have headers and so should have a header hash. Therefore there
-is probably never any reason to set this manually.
+XML files which don't have a KDBX wrapper don't have headers and so should not have a header hash. Therefore
+there is probably never any reason to set this manually.
=cut
+has allow_protection => 1;
+has binaries => sub { $_[0]->kdbx->version < KDBX_VERSION_4_0 };
+has 'compress_binaries';
+has 'compress_datetimes';
+
sub header_hash { $_[0]->{header_hash} }
sub _binaries_written { $_[0]->{_binaries_written} //= {} }
my $new_ref = keys %{$self->_binaries_written};
my $written = $self->_binaries_written;
- my $entries = $kdbx->all_entries(history => true);
- for my $entry (@$entries) {
+ my $entries = $kdbx->entries(history => 1);
+ while (my $entry = $entries->next) {
for my $key (keys %{$entry->binaries}) {
my $binary = $entry->binaries->{$key};
if (defined $binary->{ref} && defined $kdbx->binaries->{$binary->{ref}}) {
my $self = shift;
my $node = shift;
- my $custom_icons = $self->kdbx->meta->{custom_icons} || {};
+ my $custom_icons = $self->kdbx->custom_icons;
- for my $uuid (sort keys %$custom_icons) {
- my $icon = $custom_icons->{$uuid};
+ for my $icon (@$custom_icons) {
+ $icon->{uuid} && $icon->{data} or next;
my $icon_node = $node->addNewChild(undef, 'Icon');
$self->_write_xml_from_pairs($icon_node, $icon,
if (my $group = $kdbx->root) {
my $group_node = $node->addNewChild(undef, 'Group');
- $self->_write_xml_group($group_node, $group->_confirmed);
+ $self->_write_xml_group($group_node, $group->_committed);
}
undef $guard; # re-lock if needed, as early as possible
for my $entry (@{$group->entries}) {
my $entry_node = $node->addNewChild(undef, 'Entry');
- $self->_write_xml_entry($entry_node, $entry->_confirmed);
+ $self->_write_xml_entry($entry_node, $entry->_committed);
}
for my $group (@{$group->groups}) {
my $group_node = $node->addNewChild(undef, 'Group');
- $self->_write_xml_group($group_node, $group->_confirmed);
+ $self->_write_xml_group($group_node, $group->_committed);
}
}
my $history_node = $node->addNewChild(undef, 'History');
for my $historical (@history) {
my $historical_node = $history_node->addNewChild(undef, 'Entry');
- $self->_write_xml_entry($historical_node, $historical->_confirmed, 1);
+ $self->_write_xml_entry($historical_node, $historical->_committed, 1);
}
}
}
}
sub _encode_datetime {
- goto &_encode_datetime_binary if defined $_[2] && KDBX_VERSION_4_0 <= $_[2];
local $_ = shift;
return $_->strftime('%Y-%m-%dT%H:%M:%SZ');
}