diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/File-Glob/Glob.xs | 26 | ||||
-rw-r--r-- | ext/File-Glob/t/basic.t | 6 |
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 '...'"; |