summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Whitley2000-07-14 23:24:00 +0000
committerMark Whitley2000-07-14 23:24:00 +0000
commit464c5de00d3dfb5f01e866f703d95bbb2bb9443c (patch)
treec770d2ac4df0293c245dc246f93abf500545d865
parent70705d7c9681b4ea870ea11d0c569d81e5822169 (diff)
downloadbusybox-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.zip
busybox-464c5de00d3dfb5f01e866f703d95bbb2bb9443c.tar.gz
Fixed a couple of buglets:
- add_cmd_str: segv's were being generated if there was a '# comment' line (and probably other kinds of lines, too) that was not followed by a semi-colon or whitespace - parse_edit_cmd: was returning a wrong number (too low) for the index; it was not accounting for backslashes eaten, for the fact that we start at the 3rd index in the string, or for the fact that we add an extra newline. - parse_cmd_str: was returning a wrong number (again, too low) for the index in the case of single-letter commands (p,d). There was some over-compensation for this in the 'return' stmt at the end which also needed some help. - load_cmd_file: was not eating trailing newlines off the line read from the command file. This had the deleterious effect of printing an extra newlines after text displayed from edit (i,a,c) commands.
-rw-r--r--editors/sed.c35
-rw-r--r--sed.c35
2 files changed, 58 insertions, 12 deletions
diff --git a/editors/sed.c b/editors/sed.c
index 40400fe..1f1e906 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -307,6 +307,7 @@ out:
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
{
int idx = 0;
+ int slashes_eaten = 0;
char *ptr; /* shorthand */
/*
@@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) {
idx++;
if (!ptr[idx]) {
- ptr[idx] = '\n';
- ptr[idx+1] = 0;
- return idx;
+ goto out;
}
}
/* move the newline over the '\' before it (effectively eats the '\') */
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
ptr[strlen(ptr)-1] = 0;
+ slashes_eaten++;
/* substitue \r for \n if needed */
if (ptr[idx] == '\r')
ptr[idx] = '\n';
}
+out:
+ ptr[idx] = '\n';
+ ptr[idx+1] = 0;
+
+ /* this accounts for discrepancies between the modified string and the
+ * original string passed in to this function */
+ idx += slashes_eaten;
+
+ /* this accounts for the fact that A) we started at index 3, not at index
+ * 0 and B) that we added an extra '\n' at the end (if you think the next
+ * line should read 'idx += 4' remember, arrays are zero-based) */
+
+ idx += 3;
+
return idx;
}
@@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
fatalError("only a beginning address can be specified for edit commands\n");
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
}
+ /* if it was a single-letter command (such as 'p' or 'd') we need to
+ * increment the index past that command */
+ else
+ idx++;
/* give back whatever's left over */
- return (char *)&cmdstr[++idx];
+ return (char *)&cmdstr[idx];
}
static void add_cmd_str(const char *cmdstr)
@@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr)
/* trim leading whitespace and semicolons */
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
/* if we ate the whole thing, that means there was just trailing
- * whitespace or a final semicolon. either way, get out */
+ * whitespace or a final / no-op semicolon. either way, get out */
if (strlen(mystr) == 0)
return;
/* if this is a comment, jump past it and keep going */
@@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr)
/* load command string into new array element, get remainder */
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
- } while (mystr);
+ } while (mystr && strlen(mystr));
}
@@ -447,7 +465,12 @@ static void load_cmd_file(char *filename)
(nextline = get_line_from_file(cmdfile)) != NULL) {
line = realloc(line, strlen(line) + strlen(nextline) + 1);
strcat(line, nextline);
+ free(nextline);
}
+ /* eat trailing newline (if any) --if I don't do this, edit commands
+ * (aic) will print an extra newline */
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = 0;
add_cmd_str(line);
free(line);
}
diff --git a/sed.c b/sed.c
index 40400fe..1f1e906 100644
--- a/sed.c
+++ b/sed.c
@@ -307,6 +307,7 @@ out:
static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
{
int idx = 0;
+ int slashes_eaten = 0;
char *ptr; /* shorthand */
/*
@@ -346,19 +347,32 @@ static int parse_edit_cmd(struct sed_cmd *sed_cmd, const char *editstr)
while (ptr[idx] != '\\' && (ptr[idx+1] != '\n' || ptr[idx+1] != '\r')) {
idx++;
if (!ptr[idx]) {
- ptr[idx] = '\n';
- ptr[idx+1] = 0;
- return idx;
+ goto out;
}
}
/* move the newline over the '\' before it (effectively eats the '\') */
memmove(&ptr[idx], &ptr[idx+1], strlen(&ptr[idx+1]));
ptr[strlen(ptr)-1] = 0;
+ slashes_eaten++;
/* substitue \r for \n if needed */
if (ptr[idx] == '\r')
ptr[idx] = '\n';
}
+out:
+ ptr[idx] = '\n';
+ ptr[idx+1] = 0;
+
+ /* this accounts for discrepancies between the modified string and the
+ * original string passed in to this function */
+ idx += slashes_eaten;
+
+ /* this accounts for the fact that A) we started at index 3, not at index
+ * 0 and B) that we added an extra '\n' at the end (if you think the next
+ * line should read 'idx += 4' remember, arrays are zero-based) */
+
+ idx += 3;
+
return idx;
}
@@ -398,9 +412,13 @@ static char *parse_cmd_str(struct sed_cmd *sed_cmd, const char *cmdstr)
fatalError("only a beginning address can be specified for edit commands\n");
idx += parse_edit_cmd(sed_cmd, &cmdstr[idx]);
}
+ /* if it was a single-letter command (such as 'p' or 'd') we need to
+ * increment the index past that command */
+ else
+ idx++;
/* give back whatever's left over */
- return (char *)&cmdstr[++idx];
+ return (char *)&cmdstr[idx];
}
static void add_cmd_str(const char *cmdstr)
@@ -412,7 +430,7 @@ static void add_cmd_str(const char *cmdstr)
/* trim leading whitespace and semicolons */
memmove(mystr, &mystr[strspn(mystr, "; \n\r\t\v")], strlen(mystr));
/* if we ate the whole thing, that means there was just trailing
- * whitespace or a final semicolon. either way, get out */
+ * whitespace or a final / no-op semicolon. either way, get out */
if (strlen(mystr) == 0)
return;
/* if this is a comment, jump past it and keep going */
@@ -427,7 +445,7 @@ static void add_cmd_str(const char *cmdstr)
/* load command string into new array element, get remainder */
mystr = parse_cmd_str(&sed_cmds[ncmds-1], mystr);
- } while (mystr);
+ } while (mystr && strlen(mystr));
}
@@ -447,7 +465,12 @@ static void load_cmd_file(char *filename)
(nextline = get_line_from_file(cmdfile)) != NULL) {
line = realloc(line, strlen(line) + strlen(nextline) + 1);
strcat(line, nextline);
+ free(nextline);
}
+ /* eat trailing newline (if any) --if I don't do this, edit commands
+ * (aic) will print an extra newline */
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = 0;
add_cmd_str(line);
free(line);
}