diff options
author | tjr <tjr@FreeBSD.org> | 2002-06-15 07:38:27 +0000 |
---|---|---|
committer | tjr <tjr@FreeBSD.org> | 2002-06-15 07:38:27 +0000 |
commit | 361d0dd8a73326bbaf2681ea73e1e304ecedb470 (patch) | |
tree | ed98e67c1bcab57af5f733e277fe959963a6ff17 /usr.bin/tr | |
parent | 5f3176158fe3f533332ee9f51063195b6b64b5c6 (diff) | |
download | FreeBSD-src-361d0dd8a73326bbaf2681ea73e1e304ecedb470.zip FreeBSD-src-361d0dd8a73326bbaf2681ea73e1e304ecedb470.tar.gz |
Improve parsing of character and equivalence classes:
[:*] and [=*] are parsed as `infinitely many repetitions of :' (or *)
instead of literal characters (SUSv3)
Diffstat (limited to 'usr.bin/tr')
-rw-r--r-- | usr.bin/tr/str.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/usr.bin/tr/str.c b/usr.bin/tr/str.c index 1df43dc..7f5df8f 100644 --- a/usr.bin/tr/str.c +++ b/usr.bin/tr/str.c @@ -125,20 +125,25 @@ bracket(s) switch (s->str[1]) { case ':': /* "[:class:]" */ - if ((p = strstr(s->str + 2, ":]")) == NULL) + if ((p = strchr(s->str + 2, ']')) == NULL) return (0); - *p = '\0'; + if (*(p - 1) != ':' || p - s->str < 4) + goto repeat; + *(p - 1) = '\0'; s->str += 2; genclass(s); - s->str = p + 2; + s->str = p + 1; return (1); case '=': /* "[=equiv=]" */ - if ((p = strstr(s->str + 2, "=]")) == NULL) + if ((p = strchr(s->str + 2, ']')) == NULL) return (0); + if (*(p - 1) != '=' || p - s->str < 4) + goto repeat; s->str += 2; genequiv(s); return (1); default: /* "[\###*n]" or "[#*n]" */ + repeat: if ((p = strpbrk(s->str + 2, "*]")) == NULL) return (0); if (p[0] != '*' || index(p, ']') == NULL) |