summaryrefslogtreecommitdiff
path: root/dist/Data-Dumper
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-02-03 23:09:21 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-02-03 23:11:09 -0800
commitde5ef703c7d8db6517e7d56d9c018d3ad03f210e (patch)
tree18b2b7dd939b001704ed7e45766f6af568fd5e93 /dist/Data-Dumper
parent2349afb83e6e66ff2f686fcb3e0ec67a51684811 (diff)
downloadperl-de5ef703c7d8db6517e7d56d9c018d3ad03f210e.tar.gz
[perl #58608] Fix DD’s dumping of qr|\/|
By trying to escape / as \/, DD was turning \/ into \\/, producing invalid qr//’s like qr/ \\/ /. You can’t (and don’t need to) escape a / preceded by a backslash. But you have to make sure \\/ gets escaped properly as \\\/. Counting forward from the beginning of the string and ignoring escaped characters is the proper way to do it.
Diffstat (limited to 'dist/Data-Dumper')
-rw-r--r--dist/Data-Dumper/Dumper.pm2
-rw-r--r--dist/Data-Dumper/Dumper.xs9
-rw-r--r--dist/Data-Dumper/t/qr.t3
3 files changed, 8 insertions, 6 deletions
diff --git a/dist/Data-Dumper/Dumper.pm b/dist/Data-Dumper/Dumper.pm
index fcf06ad5d9..06b5eebb49 100644
--- a/dist/Data-Dumper/Dumper.pm
+++ b/dist/Data-Dumper/Dumper.pm
@@ -373,7 +373,7 @@ sub _dump {
} else {
$pat = "$val";
}
- $pat =~ s,/,\\/,g;
+ $pat =~ s <(\\.)|/> { $1 || '\\/' }ge;
$out .= "qr/$pat/";
}
elsif ($realtype eq 'SCALAR' || $realtype eq 'REF'
diff --git a/dist/Data-Dumper/Dumper.xs b/dist/Data-Dumper/Dumper.xs
index 2ad53a15c3..afb282698a 100644
--- a/dist/Data-Dumper/Dumper.xs
+++ b/dist/Data-Dumper/Dumper.xs
@@ -463,14 +463,17 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv,
{
STRLEN rlen;
const char *rval = SvPV(val, rlen);
- const char *slash = strchr(rval, '/');
+ const char * const rend = rval+rlen;
+ const char *slash = rval;
sv_catpvn(retval, "qr/", 3);
- while (slash) {
+ for (;slash < rend; slash++) {
+ if (*slash == '\\') { ++slash; continue; }
+ if (*slash == '/') {
sv_catpvn(retval, rval, slash-rval);
sv_catpvn(retval, "\\/", 2);
rlen -= slash-rval+1;
rval = slash+1;
- slash = strchr(rval, '/');
+ }
}
sv_catpvn(retval, rval, rlen);
sv_catpvn(retval, "/", 1);
diff --git a/dist/Data-Dumper/t/qr.t b/dist/Data-Dumper/t/qr.t
index 668bc82ace..43a3c19b98 100644
--- a/dist/Data-Dumper/t/qr.t
+++ b/dist/Data-Dumper/t/qr.t
@@ -12,8 +12,7 @@ BEGIN {
use Test::More tests => 2;
use Data::Dumper;
-TODO: {
- local $TODO = "RT#58608: Data::Dumper and slashes within qr";
+{
my $q = q| \/ |;
use Data::Dumper;
my $qr = qr{$q};