]> Dogcows Code - chaz/p5-File-KDBX/blobdiff - lib/File/KDBX/Loader/XML.pm
Prereq Time::Piece 1.33 to fix KDBX4 datetimes
[chaz/p5-File-KDBX] / lib / File / KDBX / Loader / XML.pm
index 806b261664b99605aab6d04d22d1910d2dce9737..68d1abeb1125dd71063fa6ffb4f31b6bd7e7cbbb 100644 (file)
@@ -9,22 +9,19 @@ use Encode qw(decode);
 use File::KDBX::Constants qw(:version :time);
 use File::KDBX::Error;
 use File::KDBX::Safe;
-use File::KDBX::Util qw(:text assert_64bit gunzip erase_scoped);
+use File::KDBX::Util qw(:class :int :text gunzip erase_scoped);
 use Scalar::Util qw(looks_like_number);
-use Time::Piece;
+use Time::Piece 1.33;
 use XML::LibXML::Reader;
 use boolean;
 use namespace::clean;
 
-use parent 'File::KDBX::Loader';
+extends 'File::KDBX::Loader';
 
 our $VERSION = '999.999'; # VERSION
 
-sub _reader { $_[0]->{_reader} }
-
-sub _binaries { $_[0]->{binaries} //= {} }
-
-sub _safe { $_[0]->{safe} //= File::KDBX::Safe->new(cipher => $_[0]->kdbx->random_stream) }
+has '_reader',  is => 'ro';
+has '_safe',    is => 'ro', default => sub { File::KDBX::Safe->new(cipher => $_[0]->kdbx->random_stream) };
 
 sub _read {
     my $self = shift;
@@ -39,7 +36,7 @@ sub _read_inner_body {
 
     my $reader = $self->{_reader} = XML::LibXML::Reader->new(IO => $fh);
 
-    delete $self->{safe};
+    delete $self->{_safe};
     my $root_done;
 
     my $pattern = XML::LibXML::Pattern->new('/KeePassFile/Meta|/KeePassFile/Root');
@@ -63,7 +60,7 @@ sub _read_inner_body {
         throw 'Failed to parse KeePass XML';
     }
 
-    $self->kdbx->_safe($self->_safe) if $self->{safe};
+    $self->kdbx->_safe($self->_safe) if $self->{_safe};
 
     $self->_resolve_binary_refs;
 }
@@ -168,16 +165,15 @@ sub _read_xml_custom_data {
 sub _read_xml_custom_icons {
     my $self = shift;
 
-    return $self->_read_xml_element(
+    return $self->_read_xml_element([],
         Icon    => sub {
             my $self = shift;
-            my $icon = $self->_read_xml_element(
+            $self->_read_xml_element(
                 UUID                    => 'uuid',
                 Data                    => 'binary',
                 Name                    => 'text',      # KDBX4.1
                 LastModificationTime    => 'datetime',  # KDBX4.1
             );
-            $icon->{uuid} => $icon;
         },
     );
 }
@@ -371,10 +367,10 @@ sub _resolve_binary_refs {
     my $self = shift;
     my $kdbx = $self->kdbx;
 
-    my $entries = $kdbx->all_entries(history => 1);
     my $pool = $kdbx->binaries;
 
-    for my $entry (@$entries) {
+    my $entries = $kdbx->entries(history => 1);
+    while (my $entry = $entries->next) {
         while (my ($key, $binary) = each %{$entry->binaries}) {
             my $ref = $binary->{ref} // next;
             next if defined $binary->{value};
@@ -500,7 +496,7 @@ sub _read_xml_content {
     my $decoded = eval { _decode_primitive($content, $type) };
     if (my $err = $@) {
         ref $err and $err->details(node => $reader->nodePath, line => $reader->lineNumber);
-        throw $err
+        throw $err;
     }
 
     return $decoded;
@@ -537,14 +533,12 @@ sub _decode_datetime {
             throw 'Failed to parse binary datetime', text => $_, error => $err;
         }
         throw $@ if $@;
-        assert_64bit;
         $binary .= \0 x (8 - length($binary)) if length($binary) < 8;
-        my ($seconds_since_ad1) = unpack('Q<', $binary);
+        my ($seconds_since_ad1) = unpack_Ql($binary);
         my $epoch = $seconds_since_ad1 - TIME_SECONDS_AD1_TO_UNIX_EPOCH;
-        return Time::Piece->new($epoch);
+        return gmtime($epoch);
     }
 
-
     my $dt = eval { Time::Piece->strptime($_, '%Y-%m-%dT%H:%M:%SZ') };
     if (my $err = $@) {
         throw 'Failed to parse datetime', text => $_, error => $err;
This page took 0.022949 seconds and 4 git commands to generate.