Fixed a bug where "sed 's/foo/bar/g'" (i.e. a script w/o a -e)

would go into an infinite loop.
 -Erik
This commit is contained in:
Erik Andersen 2000-03-06 19:20:35 +00:00
parent 9c5c29d442
commit e916d24805
3 changed files with 246 additions and 244 deletions

View File

@ -35,6 +35,8 @@
- Fixes to the makefile for handling "strip" - Fixes to the makefile for handling "strip"
* An initial telnet implementation was added by * An initial telnet implementation was added by
Randolph Chung <tausq@debian.org>. Randolph Chung <tausq@debian.org>.
* Fixed a bug where "sed 's/foo/bar/g'" would go into an
infinite loop.
-Erik Andersen -Erik Andersen

View File

@ -184,129 +184,129 @@ extern int sed_main(int argc, char **argv)
} }
while (argc > 1) { while (argc > 1) {
if (**argv == '-') { if (**argv != '-')
argc--; usage(sed_usage);
cp = *argv++; argc--;
stopNow = FALSE; cp = *argv++;
stopNow = FALSE;
while (*++cp && stopNow == FALSE) { while (*++cp && stopNow == FALSE) {
switch (*cp) { switch (*cp) {
case 'n': case 'n':
quietFlag = TRUE; quietFlag = TRUE;
break; break;
case 'e': case 'e':
if (*(cp + 1) == 0 && --argc < 0) { if (*(cp + 1) == 0 && --argc < 0) {
usage(sed_usage); usage(sed_usage);
} }
if (*++cp != 's') if (*++cp != 's')
cp = *argv++; cp = *argv++;
/* Read address if present */ /* Read address if present */
SKIPSPACES(cp); SKIPSPACES(cp);
if (*cp == '$') { if (*cp == '$') {
addr_line = LAST_LINE; addr_line = LAST_LINE;
cp++; cp++;
} else { } else {
if (isdigit(*cp)) { /* LINE ADDRESS */ if (isdigit(*cp)) { /* LINE ADDRESS */
line_s = cp; line_s = cp;
while (isdigit(*cp)) while (isdigit(*cp))
cp++; cp++;
if (cp > line_s) { if (cp > line_s) {
/* numeric line */ /* numeric line */
saved = *cp; saved = *cp;
*cp = '\0'; *cp = '\0';
addr_line = atoi(line_s); addr_line = atoi(line_s);
*cp = saved; *cp = saved;
} }
} else if (*cp == '/') { /* PATTERN ADDRESS */ } else if (*cp == '/') { /* PATTERN ADDRESS */
pos = addr_pattern = cp + 1; pos = addr_pattern = cp + 1;
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (!pos) if (!pos)
usage(sed_usage); usage(sed_usage);
*pos = '\0'; *pos = '\0';
cp = pos + 1; cp = pos + 1;
} }
} }
SKIPSPACES(cp); SKIPSPACES(cp);
if (*cp == '!') { if (*cp == '!') {
negated++; negated++;
cp++; cp++;
} }
/* Read command */ /* Read command */
SKIPSPACES(cp); SKIPSPACES(cp);
switch (*cp) { switch (*cp) {
case 's': /* REPLACE */ case 's': /* REPLACE */
if (strlen(cp) <= 3 || *(cp + 1) != '/') if (strlen(cp) <= 3 || *(cp + 1) != '/')
break; break;
sed_f = f_replace; sed_f = f_replace;
pos = needle = cp + 2; pos = needle = cp + 2;
for (;;) { for (;;) {
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (pos == NULL) { if (pos == NULL) {
usage(sed_usage); usage(sed_usage);
} }
if (*(pos - 1) == '\\') { if (*(pos - 1) == '\\') {
pos++; pos++;
continue; continue;
} }
break; break;
} }
*pos = 0; *pos = 0;
newNeedle = ++pos; newNeedle = ++pos;
for (;;) { for (;;) {
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (pos == NULL) { if (pos == NULL) {
usage(sed_usage); usage(sed_usage);
} }
if (*(pos - 1) == '\\') { if (*(pos - 1) == '\\') {
pos++; pos++;
continue; continue;
} }
break; break;
} }
*pos = 0; *pos = 0;
if (pos + 2 != 0) { if (pos + 2 != 0) {
while (*++pos) { while (*++pos) {
switch (*pos) { switch (*pos) {
case 'i': case 'i':
ignoreCase = TRUE; ignoreCase = TRUE;
break; break;
case 'p': case 'p':
printFlag = TRUE; printFlag = TRUE;
break; break;
case 'g': case 'g':
break; break;
default: default:
usage(sed_usage); usage(sed_usage);
} }
} }
} }
cp = pos; cp = pos;
/* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
break; break;
case 'a': /* APPEND */ case 'a': /* APPEND */
if (strlen(cp) < 2) if (strlen(cp) < 2)
break; break;
sed_f = f_append; sed_f = f_append;
appendline = ++cp; appendline = ++cp;
/* fprintf(stderr, "append '%s'\n", appendline); */ /* fprintf(stderr, "append '%s'\n", appendline); */
break; break;
} }
stopNow = TRUE; stopNow = TRUE;
break; break;
default: default:
usage(sed_usage); usage(sed_usage);
} }
} }
}
} }
if (argc == 0) { if (argc == 0) {

244
sed.c
View File

@ -184,129 +184,129 @@ extern int sed_main(int argc, char **argv)
} }
while (argc > 1) { while (argc > 1) {
if (**argv == '-') { if (**argv != '-')
argc--; usage(sed_usage);
cp = *argv++; argc--;
stopNow = FALSE; cp = *argv++;
stopNow = FALSE;
while (*++cp && stopNow == FALSE) { while (*++cp && stopNow == FALSE) {
switch (*cp) { switch (*cp) {
case 'n': case 'n':
quietFlag = TRUE; quietFlag = TRUE;
break; break;
case 'e': case 'e':
if (*(cp + 1) == 0 && --argc < 0) { if (*(cp + 1) == 0 && --argc < 0) {
usage(sed_usage); usage(sed_usage);
} }
if (*++cp != 's') if (*++cp != 's')
cp = *argv++; cp = *argv++;
/* Read address if present */ /* Read address if present */
SKIPSPACES(cp); SKIPSPACES(cp);
if (*cp == '$') { if (*cp == '$') {
addr_line = LAST_LINE; addr_line = LAST_LINE;
cp++; cp++;
} else { } else {
if (isdigit(*cp)) { /* LINE ADDRESS */ if (isdigit(*cp)) { /* LINE ADDRESS */
line_s = cp; line_s = cp;
while (isdigit(*cp)) while (isdigit(*cp))
cp++; cp++;
if (cp > line_s) { if (cp > line_s) {
/* numeric line */ /* numeric line */
saved = *cp; saved = *cp;
*cp = '\0'; *cp = '\0';
addr_line = atoi(line_s); addr_line = atoi(line_s);
*cp = saved; *cp = saved;
} }
} else if (*cp == '/') { /* PATTERN ADDRESS */ } else if (*cp == '/') { /* PATTERN ADDRESS */
pos = addr_pattern = cp + 1; pos = addr_pattern = cp + 1;
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (!pos) if (!pos)
usage(sed_usage); usage(sed_usage);
*pos = '\0'; *pos = '\0';
cp = pos + 1; cp = pos + 1;
} }
} }
SKIPSPACES(cp); SKIPSPACES(cp);
if (*cp == '!') { if (*cp == '!') {
negated++; negated++;
cp++; cp++;
} }
/* Read command */ /* Read command */
SKIPSPACES(cp); SKIPSPACES(cp);
switch (*cp) { switch (*cp) {
case 's': /* REPLACE */ case 's': /* REPLACE */
if (strlen(cp) <= 3 || *(cp + 1) != '/') if (strlen(cp) <= 3 || *(cp + 1) != '/')
break; break;
sed_f = f_replace; sed_f = f_replace;
pos = needle = cp + 2; pos = needle = cp + 2;
for (;;) { for (;;) {
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (pos == NULL) { if (pos == NULL) {
usage(sed_usage); usage(sed_usage);
} }
if (*(pos - 1) == '\\') { if (*(pos - 1) == '\\') {
pos++; pos++;
continue; continue;
} }
break; break;
} }
*pos = 0; *pos = 0;
newNeedle = ++pos; newNeedle = ++pos;
for (;;) { for (;;) {
pos = strchr(pos, '/'); pos = strchr(pos, '/');
if (pos == NULL) { if (pos == NULL) {
usage(sed_usage); usage(sed_usage);
} }
if (*(pos - 1) == '\\') { if (*(pos - 1) == '\\') {
pos++; pos++;
continue; continue;
} }
break; break;
} }
*pos = 0; *pos = 0;
if (pos + 2 != 0) { if (pos + 2 != 0) {
while (*++pos) { while (*++pos) {
switch (*pos) { switch (*pos) {
case 'i': case 'i':
ignoreCase = TRUE; ignoreCase = TRUE;
break; break;
case 'p': case 'p':
printFlag = TRUE; printFlag = TRUE;
break; break;
case 'g': case 'g':
break; break;
default: default:
usage(sed_usage); usage(sed_usage);
} }
} }
} }
cp = pos; cp = pos;
/* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */ /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
break; break;
case 'a': /* APPEND */ case 'a': /* APPEND */
if (strlen(cp) < 2) if (strlen(cp) < 2)
break; break;
sed_f = f_append; sed_f = f_append;
appendline = ++cp; appendline = ++cp;
/* fprintf(stderr, "append '%s'\n", appendline); */ /* fprintf(stderr, "append '%s'\n", appendline); */
break; break;
} }
stopNow = TRUE; stopNow = TRUE;
break; break;
default: default:
usage(sed_usage); usage(sed_usage);
} }
} }
}
} }
if (argc == 0) { if (argc == 0) {