summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/File-Glob/Glob.xs26
-rw-r--r--ext/File-Glob/t/basic.t6
2 files changed, 28 insertions, 4 deletions
diff --git a/ext/File-Glob/Glob.xs b/ext/File-Glob/Glob.xs
index 9d35ac215c..c055d1ba2f 100644
--- a/ext/File-Glob/Glob.xs
+++ b/ext/File-Glob/Glob.xs
@@ -125,6 +125,7 @@ csh_glob(pTHX)
case '"' :
{
bool found = FALSE;
+ const char quote = *s;
if (!word) {
word = newSVpvs("");
if (is_utf8) SvUTF8_on(word);
@@ -132,8 +133,14 @@ csh_glob(pTHX)
if (piece) sv_catpvn(word, piece, s-piece);
piece = s+1;
while (++s <= patend)
- if (*s == '\\') s++;
- else if (*s == *(piece-1)) {
+ if (*s == '\\') {
+ s++;
+ /* If the backslash is here to escape a quote,
+ obliterate it. */
+ if (s < patend && *s == quote)
+ sv_catpvn(word, piece, s-piece-1), piece = s;
+ }
+ else if (*s == quote) {
sv_catpvn(word, piece, s-piece);
piece = NULL;
found = TRUE;
@@ -164,7 +171,20 @@ csh_glob(pTHX)
}
break;
}
- case '\\': if (!piece) piece = s; s++; break;
+ case '\\':
+ if (!piece) piece = s;
+ s++;
+ /* If the backslash is here to escape a quote,
+ obliterate it. */
+ if (s < patend && (*s == '"' || *s == '\'')) {
+ if (!word) {
+ word = newSVpvn(piece,s-piece-1);
+ if (is_utf8) SvUTF8_on(word);
+ }
+ else sv_catpvn(word, piece, s-piece-1);
+ piece = s;
+ }
+ break;
default:
if (isSPACE(*s)) {
if (piece) {
diff --git a/ext/File-Glob/t/basic.t b/ext/File-Glob/t/basic.t
index 309e2bb456..df2b958e65 100644
--- a/ext/File-Glob/t/basic.t
+++ b/ext/File-Glob/t/basic.t
@@ -10,7 +10,7 @@ BEGIN {
}
}
use strict;
-use Test::More tests => 25;
+use Test::More tests => 29;
BEGIN {use_ok('File::Glob', ':glob')};
use Cwd ();
@@ -248,3 +248,7 @@ is_deeply [<\\* .\\*>], [<\\*>,<.\\*>], 'backslashes with(out) spaces';
like <\\ >, qr/^\\? \z/, 'final escaped space';
is <a"b>, 'a"b', 'unmatched quote';
is < a"b >, 'a"b', 'unmatched quote with surrounding spaces';
+is glob('a\"b'), 'a"b', '\ before quote *only* escapes quote';
+is glob(q"a\'b"), "a'b", '\ before single quote *only* escapes quote';
+is glob('"a\"b c\"d"'), 'a"b c"d', 'before \" within "..."';
+is glob(q"'a\'b c\'d'"), "a'b c'd", q"before \' within '...'";