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:
parent
9c5c29d442
commit
e916d24805
@ -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
|
||||||
|
244
editors/sed.c
244
editors/sed.c
@ -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
244
sed.c
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user