File Coverage

lib/SMB/Parser.pm
Criterion Covered Total %
statement 54 58 93.1
branch 6 6 100.0
condition 5 6 83.3
subroutine 21 25 84.0
pod 19 20 95.0
total 105 115 91.3


line stmt bran cond sub pod time code
1             # SMB Perl library, Copyright (C) 2014-2018 Mikhael Goikhman, migo@cpan.org
2             #
3             # This program is free software: you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation, either version 3 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package SMB::Parser;
17              
18 3     3   522 use strict;
  3         4  
  3         66  
19 3     3   10 use warnings;
  3         4  
  3         81  
20              
21 3     3   492 use bytes;
  3         14  
  3         10  
22 3     3   1550 use if (1 << 32 == 1), 'bigint'; # support native uint64 on 32-bit platforms
  3         31  
  3         10  
23 3     3   901 use Encode 'decode';
  3         14328  
  3         1688  
24              
25             sub new ($$) {
26 3     3 1 402 my $class = shift;
27 3   100     12 my $data = shift // "";
28              
29 3         4 my $self = bless {}, $class;
30              
31 3         6 return $self->set($data);
32             }
33              
34             sub reset ($;$) {
35 23     23 1 2350 my $self = shift;
36 23   100     58 my $offset = shift || 0;
37              
38 23         20 $self->{offset} = $offset;
39              
40 23         53 return $self;
41             }
42              
43             sub set ($$;$) {
44 7     7 1 9 my $self = shift;
45              
46 7         15 $self->{data} = $_[0];
47 7         10 $self->{size} = length($_[0]);
48              
49 7         16 return $self->reset($_[1]);
50             }
51              
52 1     1 1 3 sub data { $_[0]->{data} }
53 2     2 1 5 sub size { $_[0]->{size} }
54 10     10 1 39 sub offset { $_[0]->{offset} }
55              
56             my %UINT_MODS = (
57             +1 => 'C',
58             +2 => 'v',
59             +4 => 'V',
60             -1 => 'C',
61             -2 => 'n',
62             -4 => 'N',
63             );
64              
65             sub uint ($$;$) {
66 66     66 0 67 my $self = shift;
67 66         54 my $n_bytes = shift;
68 66 100       74 my $be_factor = shift() ? -1 : 1;
69              
70 66         128 return unpack($UINT_MODS{$be_factor * $n_bytes}, $self->bytes($n_bytes));
71             }
72              
73             sub str ($$;$) {
74 9     9 1 8 my $self = shift;
75 9         9 my $n_bytes = shift;
76 9   50     18 my $enc = shift || 'UTF-16LE';
77              
78 9         11 return decode($enc, $self->bytes($n_bytes));
79             }
80              
81             sub bytes ($$) {
82 90     90 1 87 my $self = shift;
83 90         66 my $n_bytes = shift;
84              
85             my $n_avail = $self->{offset} + $n_bytes > $self->{size}
86 90 100       132 ? $self->{size} - $self->{offset} : $n_bytes;
87              
88 90 100       154 my $bytes = $self->{offset} > $self->{size} ? '' : substr($self->{data}, $self->{offset}, $n_avail);
89 90         78 $self->{offset} += $n_bytes;
90              
91 90         281 return $bytes;
92             }
93              
94             sub skip ($) {
95 9     9 1 7 my $self = shift;
96 9         6 my $n_bytes = shift;
97              
98 9         8 $self->{offset} += $n_bytes;
99              
100 9         12 return $self;
101             }
102              
103 14     14 1 5449 sub uint8 { uint($_[0], 1 ); }
104 26     26 1 2054 sub uint16 { uint($_[0], 2 ); }
105 17     17 1 830 sub uint32 { uint($_[0], 4 ); }
106 6     6 1 2008 sub uint16_be { uint($_[0], 2, 1); }
107 3     3 1 800 sub uint32_be { uint($_[0], 4, 1); }
108 1     1 1 11 sub uint64 { uint32($_[0]) + (uint32($_[0]) << 32); }
109 0     0 1   sub utf16 { str($_[0], $_[1]); }
110 0     0 1   sub utf16_be { str($_[0], $_[1], 'UTF-16BE'); }
111 0     0 1   sub fid1 { uint16($_[0]); }
112 0     0 1   sub fid2 { [ uint64($_[0]), uint64($_[0]) ]; }
113              
114             1;
115              
116             __END__