File Coverage

blib/lib/Dancer/Serializer/XML.pm
Criterion Covered Total %
statement 24 58 41.3
branch 0 10 0.0
condition 0 10 0.0
subroutine 8 18 44.4
pod 4 8 50.0
total 36 104 34.6


line stmt bran cond sub pod time code
1             package Dancer::Serializer::XML;
2             our $AUTHORITY = 'cpan:SUKRIA';
3             #ABSTRACT: serializer for handling XML data
4             $Dancer::Serializer::XML::VERSION = '1.3514_04'; # TRIAL
5             $Dancer::Serializer::XML::VERSION = '1.351404';
6 166     166   1412 use strict;
  166         306  
  166         4009  
7 166     166   757 use warnings;
  166         286  
  166         3266  
8 166     166   770 use Carp;
  166         298  
  166         7918  
9 166     166   1019 use Dancer::ModuleLoader;
  166         378  
  166         4675  
10 166     166   947 use Dancer::Config 'setting';
  166         365  
  166         6814  
11 166     166   890 use base 'Dancer::Serializer::Abstract';
  166         330  
  166         69790  
12              
13             # singleton for the XML::Simple object
14             my $_xs;
15              
16             # helpers
17              
18             sub from_xml {
19 0     0 0   my $s = Dancer::Serializer::XML->new;
20 0           $s->deserialize(@_);
21             }
22              
23             sub to_xml {
24 0     0 0   my $s = Dancer::Serializer::XML->new;
25 0           $s->serialize(@_);
26             }
27              
28             # class definition
29              
30             sub loaded_xmlsimple {
31 0     0 0   Dancer::ModuleLoader->load('XML::Simple');
32             }
33              
34             sub loaded_xmlbackends {
35             # we need either XML::Parser or XML::SAX too
36 0 0   0 0   Dancer::ModuleLoader->load('XML::Parser') or
37             Dancer::ModuleLoader->load('XML::SAX');
38             }
39              
40             sub init {
41 0     0 1   my ($self) = @_;
42 0 0         die 'XML::Simple is needed and is not installed'
43             unless $self->loaded_xmlsimple;
44 0 0         die 'XML::Simple needs XML::Parser or XML::SAX and neither is installed'
45             unless $self->loaded_xmlbackends;
46             # Disable fetching external entities, as that's a security hole: this allows
47             # someone to fetch remote websites from the server, or to read local files.
48             # This only works for XML::Parser when called directly from XML::Simple;
49             # for XML::SAX we'll need to do some even *more* horrible stuff later on.
50             $_xs = XML::Simple->new(
51             ParserOpts => [
52             Handlers => {
53             ExternEnt => sub {
54 0     0     return '';
55             }
56             }
57 0           ],
58             );
59             }
60              
61             sub serialize {
62 0     0 1   my $self = shift;
63 0           my $entity = shift;
64 0           my %options = (RootName => 'data');
65              
66 0   0       my $s = setting('engines') || {};
67 0 0 0       if (exists($s->{XMLSerializer}) && exists($s->{XMLSerializer}{serialize})) {
68 0           %options = (%options, %{$s->{XMLSerializer}{serialize}});
  0            
69             }
70              
71 0           %options = (%options, @_);
72              
73              
74 0           $_xs->XMLout($entity, %options);
75             }
76              
77 0           sub deserialize {
78 0     0 1   my $self = shift;
79 0           my $xml = shift;
80 0           my %options = ();
81              
82 0   0       my $s = setting('engines') || {};
83 0 0 0       if (exists($s->{XMLSerializer}) && exists($s->{XMLSerializer}{deserialize})) {
84 0           %options = (%options, %{$s->{XMLSerializer}{deserialize}});
  0            
85             }
86              
87 0           %options = (%options, @_);
88             # This is the promised terrible hack: claim that the LWP-talking code has
89             # already been loaded, and make sure that the handler that's called when
90             # we're dealing with an external entity does nothing.
91             # For whichever reason, this handler is called despite XML::Parser
92             # (which on my machine is the only XML::SAX backend that can handle
93             # external entities) having a ParseParamEnt option which is off by default,
94             # but appears to only be used deep in the XML::Parser XS guts.
95 166     166   1159 no warnings 'redefine';
  166         389  
  166         13428  
96 0     0     local *XML::Parser::lwp_ext_ent_handler = sub { return };
  0            
97 0           local $INC{'XML/Parser/LWPExternEnt.pl'}
98             = 'Dancer::Serializer::XML disabled loading this to patch around '
99             . 'XXE vulnerabilities';
100 0           $_xs->XMLin($xml, %options);
101 166     166   1015 use warnings 'redefine';
  166         361  
  166         13405  
102             }
103              
104 0     0 1   sub content_type {'text/xml'}
105              
106             1;
107              
108             __END__