summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2011-11-22 20:00:02 -0500
committerChet Ramey <chet.ramey@case.edu>2011-11-22 20:00:02 -0500
commitd26fdfa0b92fcbc1e9bced7c4343e954db569105 (patch)
tree0e54c68c30f24c591f81ea9e7019e46b28fedefb
parent23c597e509782b3166b527b89664676bda7448b7 (diff)
downloadbash-d26fdfa0b92fcbc1e9bced7c4343e954db569105.tar.gz
Bash-4.2 patch 3
-rw-r--r--lib/glob/gmisc.c84
-rw-r--r--patchlevel.h2
2 files changed, 65 insertions, 21 deletions
diff --git a/lib/glob/gmisc.c b/lib/glob/gmisc.c
index 84794cd1..683035a2 100644
--- a/lib/glob/gmisc.c
+++ b/lib/glob/gmisc.c
@@ -77,8 +77,8 @@ wmatchlen (wpat, wmax)
wchar_t *wpat;
size_t wmax;
{
- wchar_t wc, *wbrack;
- int matlen, t, in_cclass, in_collsym, in_equiv;
+ wchar_t wc;
+ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
if (*wpat == 0)
return (0);
@@ -118,58 +118,80 @@ wmatchlen (wpat, wmax)
break;
case L'[':
/* scan for ending `]', skipping over embedded [:...:] */
- wbrack = wpat;
+ bracklen = 1;
wc = *wpat++;
do
{
if (wc == 0)
{
- matlen += wpat - wbrack - 1; /* incremented below */
- break;
+ wpat--; /* back up to NUL */
+ matlen += bracklen;
+ goto bad_bracket;
}
else if (wc == L'\\')
{
- wc = *wpat++;
- if (*wpat == 0)
- break;
+ /* *wpat == backslash-escaped character */
+ bracklen++;
+ /* If the backslash or backslash-escape ends the string,
+ bail. The ++wpat skips over the backslash escape */
+ if (*wpat == 0 || *++wpat == 0)
+ {
+ matlen += bracklen;
+ goto bad_bracket;
+ }
}
else if (wc == L'[' && *wpat == L':') /* character class */
{
wpat++;
+ bracklen++;
in_cclass = 1;
}
else if (in_cclass && wc == L':' && *wpat == L']')
{
wpat++;
+ bracklen++;
in_cclass = 0;
}
else if (wc == L'[' && *wpat == L'.') /* collating symbol */
{
wpat++;
+ bracklen++;
if (*wpat == L']') /* right bracket can appear as collating symbol */
- wpat++;
+ {
+ wpat++;
+ bracklen++;
+ }
in_collsym = 1;
}
else if (in_collsym && wc == L'.' && *wpat == L']')
{
wpat++;
+ bracklen++;
in_collsym = 0;
}
else if (wc == L'[' && *wpat == L'=') /* equivalence class */
{
wpat++;
+ bracklen++;
if (*wpat == L']') /* right bracket can appear as equivalence class */
- wpat++;
+ {
+ wpat++;
+ bracklen++;
+ }
in_equiv = 1;
}
else if (in_equiv && wc == L'=' && *wpat == L']')
{
wpat++;
+ bracklen++;
in_equiv = 0;
}
+ else
+ bracklen++;
}
while ((wc = *wpat++) != L']');
matlen++; /* bracket expression can only match one char */
+bad_bracket:
break;
}
}
@@ -213,8 +235,8 @@ umatchlen (pat, max)
char *pat;
size_t max;
{
- char c, *brack;
- int matlen, t, in_cclass, in_collsym, in_equiv;
+ char c;
+ int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
if (*pat == 0)
return (0);
@@ -254,58 +276,80 @@ umatchlen (pat, max)
break;
case '[':
/* scan for ending `]', skipping over embedded [:...:] */
- brack = pat;
+ bracklen = 1;
c = *pat++;
do
{
if (c == 0)
{
- matlen += pat - brack - 1; /* incremented below */
- break;
+ pat--; /* back up to NUL */
+ matlen += bracklen;
+ goto bad_bracket;
}
else if (c == '\\')
{
- c = *pat++;
- if (*pat == 0)
- break;
+ /* *pat == backslash-escaped character */
+ bracklen++;
+ /* If the backslash or backslash-escape ends the string,
+ bail. The ++pat skips over the backslash escape */
+ if (*pat == 0 || *++pat == 0)
+ {
+ matlen += bracklen;
+ goto bad_bracket;
+ }
}
else if (c == '[' && *pat == ':') /* character class */
{
pat++;
+ bracklen++;
in_cclass = 1;
}
else if (in_cclass && c == ':' && *pat == ']')
{
pat++;
+ bracklen++;
in_cclass = 0;
}
else if (c == '[' && *pat == '.') /* collating symbol */
{
pat++;
+ bracklen++;
if (*pat == ']') /* right bracket can appear as collating symbol */
- pat++;
+ {
+ pat++;
+ bracklen++;
+ }
in_collsym = 1;
}
else if (in_collsym && c == '.' && *pat == ']')
{
pat++;
+ bracklen++;
in_collsym = 0;
}
else if (c == '[' && *pat == '=') /* equivalence class */
{
pat++;
+ bracklen++;
if (*pat == ']') /* right bracket can appear as equivalence class */
- pat++;
+ {
+ pat++;
+ bracklen++;
+ }
in_equiv = 1;
}
else if (in_equiv && c == '=' && *pat == ']')
{
pat++;
+ bracklen++;
in_equiv = 0;
}
+ else
+ bracklen++;
}
while ((c = *pat++) != ']');
matlen++; /* bracket expression can only match one char */
+bad_bracket:
break;
}
}
diff --git a/patchlevel.h b/patchlevel.h
index 9355623d..3f5e06c9 100644
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
-#define PATCHLEVEL 2
+#define PATCHLEVEL 3
#endif /* _PATCHLEVEL_H_ */