summaryrefslogtreecommitdiff
path: root/sed/debug.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2022-12-19 12:32:21 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2022-12-19 12:35:32 -0800
commita9b1b679b6cbe94087708fe8957979182d501528 (patch)
treecadd34080882a8a4c5665963451db56a55d5533c /sed/debug.c
parentfc0655d78220ed5533b3e34c52c8fc1fc9719061 (diff)
downloadsed-a9b1b679b6cbe94087708fe8957979182d501528.tar.gz
sed: improve integer overflow checking
Fix some some longstanding but unlikely integer overflows. Internally, 'sed' now more often prefers signed integer arithmetic, which can be checked automatically via 'gcc -fsanitize=undefined'. * basicdefs.h (countT): Remove. All uses replaced with a more-specific signed type, e.g., idx_t. Similarly, change uses of types like size_t to signed types like idx_t when appropriate. (REALLOC): Remove; no longer used. We now use xpalloc because that detects integer overflow in size calculations. Also, we no longer use XCALLOC since the code never relies on the storage being zero, and leaving it uninitialized is more likely to catch errors when debugging implementations are used. We use XNMALLOC instead, or xpalloc. * bootstrap.conf (gnulib_modules): Add stdckdint, strtoimax. * lib/.gitignore, m4/.gitignore: Update for new Gnulib modules. * sed/compile.c: Include stdckdint.h. (VECTOR_ALLOC_INCREMENT): Remove; no longer used. (in_integer): Return maximal value if integer overflow. All callers changed to expect this. (next_cmd_entry): Use xpalloc instead of reallocating by hand, which might suffer integer overflow. (normalize_text): Don’t rely on system-defined conversion of out-of-range size_t to int. (next_cmd_entry): Arg is now pointer, not pointer-to-pointer. All uses changed. * sed/debug.c (debug_print_function): Don’t attempt to fwrite a null pointer with a zero size. * sed/execute.c: Include <stdckdint.h>, "minmax.h". (resize_line): LEN arg is now increment, not total length, to avoid overflow when calculating total length. All uses changed. Do not assume lb->alloc * 2 cannot overflow. (resize_line, line_copy): Use xpalloc instead of doing realloc by hand, which might suffer integer overflow. (str_append_modified): Do not add n to to->length until after it's known this cannot overflow. (read_file_line): Don’t assume ssize_t fits in long. (get_backup_file_name): Don’t assume string length fits in int. Do not assume PTR-1+1 works; behavior is undefined if PTR is at buffer start. Check for integer overflow in buffer size calculation. (read_pattern_space): Check for line number overflow. (match_address_p): Check for address overflow. (debug_print_line): Omit unnecessary test for in->active being null. (execute_program): Check for Q overflow. * sed/regexp.c: Include <stdckdint.h>. (match_regex): Don’t assume TYPE_MAXIMUM (regoff_t) == INT_MAX. * sed/sed.c: Include inttypes.h, for strtoimax. (main): Use strtoimax, not atoi. * sed/utils.c (init_buffer): Use xmalloc and xpalloc instead of guessing sizes ourselves, and unnecessarily initializing. (resize_buffer): Remove; all callers changed to use xpalloc. (free_buffer): Don’t call free (NULL), since we already test whether the pointer is null.
Diffstat (limited to 'sed/debug.c')
-rw-r--r--sed/debug.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/sed/debug.c b/sed/debug.c
index 24d6d95..78a470a 100644
--- a/sed/debug.c
+++ b/sed/debug.c
@@ -70,7 +70,7 @@ debug_print_char (char c)
}
static void
-debug_print_regex_pattern (const char *pat, size_t len)
+debug_print_regex_pattern (const char *pat, idx_t len)
{
const char *p = pat;
while (len--)
@@ -132,16 +132,16 @@ debug_print_addr (const struct addr *a)
debug_print_regex_flags (a->addr_regex, true);
break;
case ADDR_IS_NUM:
- printf ("%lu", a->addr_number);
+ printf ("%jd", a->addr_number);
break;
case ADDR_IS_NUM_MOD:
- printf ("%lu~%lu", a->addr_number, a->addr_step);
+ printf ("%jd~%jd", a->addr_number, a->addr_step);
break;
case ADDR_IS_STEP:
- printf ("+%lu", a->addr_step);
+ printf ("+%jd", a->addr_step);
break;
case ADDR_IS_STEP_MOD:
- printf ("~%lu", a->addr_step);
+ printf ("~%jd", a->addr_step);
break;
case ADDR_IS_LAST:
putchar ('$');
@@ -223,7 +223,7 @@ debug_print_subst (const struct subst *s)
if (s->print)
putchar ('p');
if (s->numb)
- printf ("%lu", s->numb);
+ printf ("%jd", s->numb);
if (s->outf)
{
putchar ('w');
@@ -234,7 +234,7 @@ debug_print_subst (const struct subst *s)
static void
debug_print_translation (const struct sed_cmd *sc)
{
- unsigned int i;
+ idx_t i;
if (mb_cur_max > 1)
{
@@ -318,7 +318,8 @@ debug_print_function (const struct vector *program, const struct sed_cmd *sc)
case 'e':
putchar (' ');
- fwrite (sc->x.cmd_txt.text, 1, sc->x.cmd_txt.text_length, stdout);
+ if (sc->x.cmd_txt.text_length)
+ fwrite (sc->x.cmd_txt.text, 1, sc->x.cmd_txt.text_length, stdout);
break;
case 'F':
@@ -343,7 +344,7 @@ debug_print_function (const struct vector *program, const struct sed_cmd *sc)
case 'q':
case 'Q':
if (sc->x.int_arg != -1)
- printf (" %d", sc->x.int_arg);
+ printf (" %jd", sc->x.int_arg);
break;
case 'n':
@@ -449,7 +450,7 @@ debug_print_program (const struct vector *program)
block_level = 1;
puts ("SED PROGRAM:");
- for (size_t i = 0; i < program->v_length; ++i)
+ for (idx_t i = 0; i < program->v_length; i++)
debug_print_command (program, &program->v[i]);
block_level = 0;
}