Localize $@ in isa and can in case of modules that mishandle eval {}
Matt S Trout [Thu, 3 Jan 2013 20:24:29 +0000 (20:24 +0000)]
Changes
lib/HTML/String/Value.pm
t/simple.t
xt/tt.t

diff --git a/Changes b/Changes
index 8660178..d150d71 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,4 @@
+  - Localize $@ in isa and can in case of modules that mishandle eval {}
   - Support for single quotes (' to ')
 
 1.000000 - 2012-08-13
index 38699ea..5adf3a9 100644 (file)
@@ -95,10 +95,17 @@ sub _hsv_is_true {
     return 1 if grep $_, map $_->[0], @{$self->{parts}};
 }
 
+# we need to local $@ here because some modules (cough, TT, cough)
+# will do a 'die $@ if $@' without realising that it wasn't their eval
+# that set it
+
 sub isa {
     my $self = shift;
     return (
-        eval { $self->_hsv_unescaped_string->isa(@_) }
+        do {
+            local $@;
+            eval { blessed($self) and $self->_hsv_unescaped_string->isa(@_) }
+        }
         or $self->SUPER::isa(@_)
     );
 }
@@ -106,7 +113,10 @@ sub isa {
 sub can {
     my $self = shift;
     return (
-        eval { $self->_hsv_unescaped_string->can(@_) }
+        do {
+            local $@;
+            eval { blessed($self) and $self->_hsv_unescaped_string->isa(@_) }
+        }
         or $self->SUPER::can(@_)
     );
 }
index 0b5e2c3..dd0d059 100644 (file)
@@ -54,5 +54,8 @@ my $expected_output = q{<tag>&lt;&gt;&amp;&quot;&#39;</tag>};
 my $html = html('<tag>').$raw_characters.html('</tag>');
 is($html, $expected_output);
 
+ok(HTML::String::Value->isa('HTML::String::Value'), 'isa on class ok');
+
+is($@, '', '$@ not set by check');
 
 done_testing;
diff --git a/xt/tt.t b/xt/tt.t
index 37e644d..8d0fab9 100644 (file)
--- a/xt/tt.t
+++ b/xt/tt.t
@@ -35,4 +35,13 @@ is(
     '<foo>"$bar"</foo>'."\n"
 );
 
+is(
+    do_tt(
+        '[% FOREACH item IN items %][% item %][% END %]',
+        { items => [ '<script>alert("lalala")</script>', '-> & so "on" <-' ] }
+    ),
+    '&lt;script&gt;alert(&quot;lalala&quot;)&lt;/script&gt;'          
+        .'-&gt; &amp; so &quot;on&quot; &lt;-'
+);
+
 done_testing;