mirror of
https://github.com/sheumann/hush.git
synced 2025-03-01 12:30:09 +00:00
Hiroshi Ito found some bugs. The 'c' command (cut and paste) was hardwired
to not put a newline at the end (which was backwards, it should have been hardwired _to_ put a newline at the end, whether or not the input line ended with a newline). Test case for that: echo | sed -e '$ctest' And then this would segfault: echo | sed -e 'g' Because pattern_space got freed but the dead pointer was only overwritten in an if statement that didn't trigger if the hold space was empty. Oops. While debugging it, I found out that the hold space is persistent between multiple input files, so I promoted it to a global and added it to the memory cleanup. The relevant test case (to compare with That Other Sed) is: echo -n woo > woo sed -e h -e g woo echo "fish" | sed -e '/woo/h' -e "izap" -e 's/woo/thingy/' -e '/fish/g' woo - And somebody gratuitously stuck in a c99 int8_t type for something that's just a flag, so I grouped the darn ints.
This commit is contained in:
parent
332c472865
commit
ce4f0e982b
@ -112,9 +112,9 @@ typedef struct sed_cmd_s {
|
|||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
/* options */
|
/* options */
|
||||||
static int be_quiet = 0, in_place=0, regex_type=0;
|
static int be_quiet, in_place, regex_type;
|
||||||
FILE *nonstdout;
|
FILE *nonstdout;
|
||||||
char *outname;
|
char *outname,*hold_space;
|
||||||
|
|
||||||
|
|
||||||
static const char bad_format_in_subst[] =
|
static const char bad_format_in_subst[] =
|
||||||
@ -122,7 +122,7 @@ static const char bad_format_in_subst[] =
|
|||||||
const char *const semicolon_whitespace = "; \n\r\t\v";
|
const char *const semicolon_whitespace = "; \n\r\t\v";
|
||||||
|
|
||||||
regmatch_t regmatch[10];
|
regmatch_t regmatch[10];
|
||||||
static regex_t *previous_regex_ptr = NULL;
|
static regex_t *previous_regex_ptr;
|
||||||
|
|
||||||
/* linked list of sed commands */
|
/* linked list of sed commands */
|
||||||
static sed_cmd_t sed_cmd_head;
|
static sed_cmd_t sed_cmd_head;
|
||||||
@ -169,6 +169,8 @@ static void free_and_close_stuff(void)
|
|||||||
free(sed_cmd);
|
free(sed_cmd);
|
||||||
sed_cmd = sed_cmd_next;
|
sed_cmd = sed_cmd_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(hold_space) free(hold_space);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -757,7 +759,7 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n
|
|||||||
|
|
||||||
static void process_file(FILE *file)
|
static void process_file(FILE *file)
|
||||||
{
|
{
|
||||||
char *pattern_space, *next_line, *hold_space=NULL;
|
char *pattern_space, *next_line;
|
||||||
static int linenum = 0, missing_newline=0;
|
static int linenum = 0, missing_newline=0;
|
||||||
int no_newline,next_no_newline=0;
|
int no_newline,next_no_newline=0;
|
||||||
|
|
||||||
@ -908,7 +910,7 @@ restart:
|
|||||||
/* Cut and paste text (replace) */
|
/* Cut and paste text (replace) */
|
||||||
case 'c':
|
case 'c':
|
||||||
/* Only triggers on last line of a matching range. */
|
/* Only triggers on last line of a matching range. */
|
||||||
if (!sed_cmd->in_match) sed_puts(sed_cmd->string,1);
|
if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0);
|
||||||
goto discard_line;
|
goto discard_line;
|
||||||
|
|
||||||
/* Read file, append contents to output */
|
/* Read file, append contents to output */
|
||||||
@ -1007,10 +1009,7 @@ restart:
|
|||||||
}
|
}
|
||||||
case 'g': /* Replace pattern space with hold space */
|
case 'g': /* Replace pattern space with hold space */
|
||||||
free(pattern_space);
|
free(pattern_space);
|
||||||
if (hold_space) {
|
pattern_space = strdup(hold_space ? hold_space : "");
|
||||||
pattern_space = strdup(hold_space);
|
|
||||||
no_newline=0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'G': /* Append newline and hold space to pattern space */
|
case 'G': /* Append newline and hold space to pattern space */
|
||||||
{
|
{
|
||||||
@ -1096,9 +1095,7 @@ static void add_cmd_block(char *cmdstr)
|
|||||||
|
|
||||||
extern int sed_main(int argc, char **argv)
|
extern int sed_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int status = EXIT_SUCCESS;
|
int status = EXIT_SUCCESS, opt, getpat = 1;
|
||||||
int opt;
|
|
||||||
uint8_t getpat = 1;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_CLEAN_UP
|
#ifdef CONFIG_FEATURE_CLEAN_UP
|
||||||
/* destroy command strings on exit */
|
/* destroy command strings on exit */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user