I'm trying to use SVG.pm for the first time in a while and ran into some
problems duplicating an SVG file I generated from another program.
In particular, I had a newline in a <desc/> element because the
description was a little long. This change resulted in two pieces of
unexpected behavior.
1. An error message:
Argument "\n" isn't numeric in chr at .../SVG/XML.pm line 59.
2. The description was all one line.
A little troubleshooting shows that the xmlescp() function was using
'chr' instead of 'ord' to deal with characters in the range '\x01' to
'\x1f'. It was also converting "\n" and "\t", which do not need escaping.
The attached patch updates t/23-xmlescape.t to cover this case and
changes SVG/XML.pm to match the expected behavior.
Subject: | xmlescape-bug.patch |
From b2dbf790a61319fbc5c9024becb2fb40cd18d5b5 Mon Sep 17 00:00:00 2001
From: G. Wade Johnson <wade@anomaly.org>
Date: Fri, 20 Mar 2009 18:06:39 -0500
Subject: [PATCH] Corrected xmlescape issues with tab, newline, and control characters.
---
lib/SVG/XML.pm | 2 +-
t/23-xmlescape.t | 12 +++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/SVG/XML.pm b/lib/SVG/XML.pm
index 813c5ce..4ce104d 100644
--- a/lib/SVG/XML.pm
+++ b/lib/SVG/XML.pm
@@ -56,7 +56,7 @@ sub xmlescp ($) {
$s=~s/\"/"/g;
$s=~s/\'/'/g;
$s=~s/\`/'/g;
- $s=~s/([\x00-\x1f])/sprintf('&#x%02X;',chr($1))/eg;
+ $s=~s/([\x00-\x08\x0b\x1f])/sprintf('&#x%02X;',ord($1))/eg;
#per suggestion from Adam Schneider
$s=~s/([\200-\377])/'&#'.ord($1).';'/ge;
diff --git a/t/23-xmlescape.t b/t/23-xmlescape.t
index a17e56f..4e0702a 100755
--- a/t/23-xmlescape.t
+++ b/t/23-xmlescape.t
@@ -1,4 +1,4 @@
-use Test::More tests=>3;
+use Test::More tests=>10;
use strict;
use SVG;
@@ -10,3 +10,13 @@ ok(my $out2 = $svg->text()->cdata("><!&"),"toxic characters to cdata");
$svg->xmlify();
ok($out1->xmlify() eq $out2->xmlify(),"xmlesc helper");
+like( $out1->xmlify(), qr/><!&/, 'Correct entities' );
+
+ok( my $out3 = $svg->text()->cdata( "Line one\nLine two" ), 'New line should be allowed.' );
+like( $out3->xmlify(), qr/one\nLine/, 'New line character is still intact.' );
+
+ok( my $out4 = $svg->text()->cdata( "\tindented" ), 'Tab should be allowed.' );
+like( $out4->xmlify(), qr/\tindented/, 'Tab character is still intact.' );
+
+ok( my $out5 = $svg->text()->cdata( "Escape these: \x01, \x08, \x0b, \x1f." ), 'Restricted characters accepted' );
+like( $out5->xmlify(), qr/, , , /, 'Restricted characters escaped' );
--
1.5.4.3