File Coverage

blib/lib/MooseX/Storage/Base/WithChecksum.pm
Criterion Covered Total %
statement 39 41 95.1
branch 6 8 75.0
condition 5 5 100.0
subroutine 8 8 100.0
pod n/a
total 58 62 93.5


line stmt bran cond sub pod time code
1             package MooseX::Storage::Base::WithChecksum;
2             # ABSTRACT: A more secure serialization role
3              
4             our $VERSION = '0.50';
5              
6 1     1   731 use Moose::Role;
  1         1  
  1         14  
7             with 'MooseX::Storage::Basic';
8              
9 1     1   6291 use Digest ();
  1         514  
  1         17  
10 1     1   864 use Data::Dumper ();
  1         6976  
  1         28  
11 1     1   8 use Carp 'confess';
  1         1  
  1         60  
12 1     1   5 use namespace::autoclean;
  1         1  
  1         10  
13              
14             our $DIGEST_MARKER = '__DIGEST__';
15              
16             around pack => sub {
17             my $orig = shift;
18             my $self = shift;
19             my @args = @_;
20              
21             my $collapsed = $self->$orig( @args );
22              
23             $collapsed->{$DIGEST_MARKER} = $self->_digest_packed($collapsed, @args);
24              
25             return $collapsed;
26             };
27              
28             around unpack => sub {
29             my ($orig, $class, $data, @args) = @_;
30              
31             # check checksum on data
32             my $old_checksum = delete $data->{$DIGEST_MARKER};
33              
34             my $checksum = $class->_digest_packed($data, @args);
35              
36             ($checksum eq $old_checksum)
37             || confess "Bad Checksum got=($checksum) expected=($old_checksum)";
38              
39             $class->$orig( $data, @args );
40             };
41              
42              
43             sub _digest_packed {
44 21     21   38 my ( $self, $collapsed, @args ) = @_;
45              
46 21         58 my $d = $self->_digest_object(@args);
47              
48             {
49 21         703 local $Data::Dumper::Indent = 0;
  21         30  
50 21         26 local $Data::Dumper::Sortkeys = 1;
51 21         26 local $Data::Dumper::Terse = 1;
52 21         23 local $Data::Dumper::Useqq = 0;
53 21         27 local $Data::Dumper::Deparse = 0; # FIXME?
54 21         55 my $str = Data::Dumper::Dumper($collapsed);
55             # NOTE:
56             # Canonicalize numbers to strings even if it
57             # mangles numbers inside strings. It really
58             # does not matter since its just the checksum
59             # anyway.
60             # - YK/SL
61 21         2743 $str =~ s/(?<! ['"] ) \b (\d+) \b (?! ['"] )/'$1'/gx;
62 21         105 $d->add( $str );
63             }
64              
65 21         205 return $d->hexdigest;
66             }
67              
68             sub _digest_object {
69 21     21   45 my ( $self, %options ) = @_;
70 21         31 my $digest_opts = $options{digest};
71              
72 21 100 100     97 $digest_opts = [ $digest_opts ]
73             if !ref($digest_opts) or ref($digest_opts) ne 'ARRAY';
74              
75 21         38 my ( $d, @args ) = @$digest_opts;
76              
77 21 100       43 if ( ref $d ) {
78 5 50       45 if ( $d->can("clone") ) {
    50          
79 0         0 return $d->clone;
80             }
81             elsif ( $d->can("reset") ) {
82 5         18 $d->reset;
83 5         87 return $d;
84             }
85             else {
86 0         0 die "Can't clone or reset digest object: $d";
87             }
88             }
89             else {
90 16   100     94 return Digest->new($d || "SHA-1", @args);
91             }
92             }
93              
94 1     1   513 no Moose::Role;
  1         2  
  1         16  
95              
96             1;
97              
98             __END__
99              
100             =pod
101              
102             =encoding UTF-8
103              
104             =head1 NAME
105              
106             MooseX::Storage::Base::WithChecksum - A more secure serialization role
107              
108             =head1 VERSION
109              
110             version 0.50
111              
112             =head1 DESCRIPTION
113              
114             This is an early implementation of a more secure Storage role,
115             which does integrity checks on the data. It is still being
116             developed so I recommend using it with caution.
117              
118             Any thoughts, ideas or suggestions on improving our technique
119             are very welcome.
120              
121             =head1 METHODS
122              
123             =over 4
124              
125             =item B<pack (?$salt)>
126              
127             =item B<unpack ($data, ?$salt)>
128              
129             =back
130              
131             =head2 Introspection
132              
133             =over 4
134              
135             =item B<meta>
136              
137             =back
138              
139             =head1 BUGS
140              
141             All complex software has bugs lurking in it, and this module is no
142             exception. If you find a bug please or add the bug to cpan-RT
143             at L<https://rt.cpan.org/Dist/Display.html?Queue=MooseX-Storage>.
144              
145             =head1 AUTHORS
146              
147             =over 4
148              
149             =item *
150              
151             Chris Prather <chris.prather@iinteractive.com>
152              
153             =item *
154              
155             Stevan Little <stevan.little@iinteractive.com>
156              
157             =item *
158              
159             יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
160              
161             =back
162              
163             =head1 COPYRIGHT AND LICENSE
164              
165             This software is copyright (c) 2007 by Infinity Interactive, Inc..
166              
167             This is free software; you can redistribute it and/or modify it under
168             the same terms as the Perl 5 programming language system itself.
169              
170             =cut