Bash-4.2 patch 3

This commit is contained in:
Chet Ramey 2011-11-22 20:00:02 -05:00
commit d26fdfa0b9
2 changed files with 65 additions and 21 deletions

View file

@ -77,8 +77,8 @@ wmatchlen (wpat, wmax)
wchar_t *wpat; wchar_t *wpat;
size_t wmax; size_t wmax;
{ {
wchar_t wc, *wbrack; wchar_t wc;
int matlen, t, in_cclass, in_collsym, in_equiv; int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
if (*wpat == 0) if (*wpat == 0)
return (0); return (0);
@ -118,58 +118,80 @@ wmatchlen (wpat, wmax)
break; break;
case L'[': case L'[':
/* scan for ending `]', skipping over embedded [:...:] */ /* scan for ending `]', skipping over embedded [:...:] */
wbrack = wpat; bracklen = 1;
wc = *wpat++; wc = *wpat++;
do do
{ {
if (wc == 0) if (wc == 0)
{ {
matlen += wpat - wbrack - 1; /* incremented below */ wpat--; /* back up to NUL */
break; matlen += bracklen;
goto bad_bracket;
} }
else if (wc == L'\\') else if (wc == L'\\')
{ {
wc = *wpat++; /* *wpat == backslash-escaped character */
if (*wpat == 0) bracklen++;
break; /* 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 */ else if (wc == L'[' && *wpat == L':') /* character class */
{ {
wpat++; wpat++;
bracklen++;
in_cclass = 1; in_cclass = 1;
} }
else if (in_cclass && wc == L':' && *wpat == L']') else if (in_cclass && wc == L':' && *wpat == L']')
{ {
wpat++; wpat++;
bracklen++;
in_cclass = 0; in_cclass = 0;
} }
else if (wc == L'[' && *wpat == L'.') /* collating symbol */ else if (wc == L'[' && *wpat == L'.') /* collating symbol */
{ {
wpat++; wpat++;
bracklen++;
if (*wpat == L']') /* right bracket can appear as collating symbol */ if (*wpat == L']') /* right bracket can appear as collating symbol */
wpat++; {
wpat++;
bracklen++;
}
in_collsym = 1; in_collsym = 1;
} }
else if (in_collsym && wc == L'.' && *wpat == L']') else if (in_collsym && wc == L'.' && *wpat == L']')
{ {
wpat++; wpat++;
bracklen++;
in_collsym = 0; in_collsym = 0;
} }
else if (wc == L'[' && *wpat == L'=') /* equivalence class */ else if (wc == L'[' && *wpat == L'=') /* equivalence class */
{ {
wpat++; wpat++;
bracklen++;
if (*wpat == L']') /* right bracket can appear as equivalence class */ if (*wpat == L']') /* right bracket can appear as equivalence class */
wpat++; {
wpat++;
bracklen++;
}
in_equiv = 1; in_equiv = 1;
} }
else if (in_equiv && wc == L'=' && *wpat == L']') else if (in_equiv && wc == L'=' && *wpat == L']')
{ {
wpat++; wpat++;
bracklen++;
in_equiv = 0; in_equiv = 0;
} }
else
bracklen++;
} }
while ((wc = *wpat++) != L']'); while ((wc = *wpat++) != L']');
matlen++; /* bracket expression can only match one char */ matlen++; /* bracket expression can only match one char */
bad_bracket:
break; break;
} }
} }
@ -213,8 +235,8 @@ umatchlen (pat, max)
char *pat; char *pat;
size_t max; size_t max;
{ {
char c, *brack; char c;
int matlen, t, in_cclass, in_collsym, in_equiv; int matlen, bracklen, t, in_cclass, in_collsym, in_equiv;
if (*pat == 0) if (*pat == 0)
return (0); return (0);
@ -254,58 +276,80 @@ umatchlen (pat, max)
break; break;
case '[': case '[':
/* scan for ending `]', skipping over embedded [:...:] */ /* scan for ending `]', skipping over embedded [:...:] */
brack = pat; bracklen = 1;
c = *pat++; c = *pat++;
do do
{ {
if (c == 0) if (c == 0)
{ {
matlen += pat - brack - 1; /* incremented below */ pat--; /* back up to NUL */
break; matlen += bracklen;
goto bad_bracket;
} }
else if (c == '\\') else if (c == '\\')
{ {
c = *pat++; /* *pat == backslash-escaped character */
if (*pat == 0) bracklen++;
break; /* 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 */ else if (c == '[' && *pat == ':') /* character class */
{ {
pat++; pat++;
bracklen++;
in_cclass = 1; in_cclass = 1;
} }
else if (in_cclass && c == ':' && *pat == ']') else if (in_cclass && c == ':' && *pat == ']')
{ {
pat++; pat++;
bracklen++;
in_cclass = 0; in_cclass = 0;
} }
else if (c == '[' && *pat == '.') /* collating symbol */ else if (c == '[' && *pat == '.') /* collating symbol */
{ {
pat++; pat++;
bracklen++;
if (*pat == ']') /* right bracket can appear as collating symbol */ if (*pat == ']') /* right bracket can appear as collating symbol */
pat++; {
pat++;
bracklen++;
}
in_collsym = 1; in_collsym = 1;
} }
else if (in_collsym && c == '.' && *pat == ']') else if (in_collsym && c == '.' && *pat == ']')
{ {
pat++; pat++;
bracklen++;
in_collsym = 0; in_collsym = 0;
} }
else if (c == '[' && *pat == '=') /* equivalence class */ else if (c == '[' && *pat == '=') /* equivalence class */
{ {
pat++; pat++;
bracklen++;
if (*pat == ']') /* right bracket can appear as equivalence class */ if (*pat == ']') /* right bracket can appear as equivalence class */
pat++; {
pat++;
bracklen++;
}
in_equiv = 1; in_equiv = 1;
} }
else if (in_equiv && c == '=' && *pat == ']') else if (in_equiv && c == '=' && *pat == ']')
{ {
pat++; pat++;
bracklen++;
in_equiv = 0; in_equiv = 0;
} }
else
bracklen++;
} }
while ((c = *pat++) != ']'); while ((c = *pat++) != ']');
matlen++; /* bracket expression can only match one char */ matlen++; /* bracket expression can only match one char */
bad_bracket:
break; break;
} }
} }

View file

@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */ looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 2 #define PATCHLEVEL 3
#endif /* _PATCHLEVEL_H_ */ #endif /* _PATCHLEVEL_H_ */