From: Paul Eggert Date: Thu, 7 Nov 2024 20:51:04 +0000 (-0800) Subject: expand: check for colno overflow X-Git-Tag: v9.6~106 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7572abed94323f0d566a531e8efba7793602ea3a;p=thirdparty%2Fcoreutils.git expand: check for colno overflow * src/expand-common.c (get_next_tab_column): Check for tab stop overflow here. All callers changed to not check. * src/expand.c (expand): Use colno for column number. --- diff --git a/src/expand-common.c b/src/expand-common.c index 7c0ea2ea76..e3f9ea84ec 100644 --- a/src/expand-common.c +++ b/src/expand-common.c @@ -271,44 +271,54 @@ finalize_tab_stops (void) } +/* Return number of first tab stop after COLUMN. TAB_INDEX specifies + amny multiple tab-sizes. Set *LAST_TAB depending on whether we are + returning COLUMN + 1 merely because we're past the last tab. + If the number would overflow, diagnose this and exit. */ extern colno -get_next_tab_column (const colno column, idx_t *tab_index, - bool *last_tab) +get_next_tab_column (colno column, idx_t *tab_index, bool *last_tab) { *last_tab = false; + colno tab_distance; /* single tab-size - return multiples of it */ if (tab_size) - return column + (tab_size - column % tab_size); - - /* multiple tab-sizes - iterate them until the tab position is beyond - the current input column. */ - for ( ; *tab_index < first_free_tab ; (*tab_index)++ ) + tab_distance = tab_size - column % tab_size; + else { - colno tab = tab_list[*tab_index]; - if (column < tab) + /* multiple tab-sizes - iterate them until the tab position is beyond + the current input column. */ + for ( ; *tab_index < first_free_tab ; (*tab_index)++ ) + { + colno tab = tab_list[*tab_index]; + if (column < tab) return tab; - } - - /* relative last tab - return multiples of it */ - if (extend_size) - return column + (extend_size - column % extend_size); - - /* incremental last tab - add increment_size to the previous tab stop */ - if (increment_size) - { - colno end_tab = tab_list[first_free_tab - 1]; + } - return column + (increment_size - ((column - end_tab) % increment_size)); + /* relative last tab - return multiples of it */ + if (extend_size) + tab_distance = extend_size - column % extend_size; + else if (increment_size) + { + /* incremental last tab - add increment_size to the previous + tab stop */ + colno end_tab = tab_list[first_free_tab - 1]; + tab_distance = increment_size - ((column - end_tab) % increment_size); + } + else + { + *last_tab = true; + tab_distance = 1; + } } - *last_tab = true; - return 0; + colno tab_stop; + if (ckd_add (&tab_stop, column, tab_distance)) + error (EXIT_FAILURE, 0, _("input line is too long")); + return tab_stop; } - - /* Sets new file-list */ extern void set_file_list (char **list) diff --git a/src/expand.c b/src/expand.c index 419cf19dff..9f950ecd47 100644 --- a/src/expand.c +++ b/src/expand.c @@ -113,7 +113,7 @@ expand (void) is true: */ /* Column of next input character. */ - uintmax_t column = 0; + colno column = 0; /* Index in TAB_LIST of next tab stop to examine. */ idx_t tab_index = 0; @@ -131,17 +131,9 @@ expand (void) if (c == '\t') { /* Column the next input tab stop is on. */ - uintmax_t next_tab_column; bool last_tab; - - next_tab_column = get_next_tab_column (column, &tab_index, - &last_tab); - - if (last_tab) - next_tab_column = column + 1; - - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); + colno next_tab_column + = get_next_tab_column (column, &tab_index, &last_tab); while (++column < next_tab_column) if (putchar (' ') < 0) @@ -158,8 +150,7 @@ expand (void) } else { - column++; - if (!column) + if (ckd_add (&column, column, 1)) error (EXIT_FAILURE, 0, _("input line is too long")); } diff --git a/src/unexpand.c b/src/unexpand.c index 9e621929a2..0d10ffe393 100644 --- a/src/unexpand.c +++ b/src/unexpand.c @@ -175,9 +175,6 @@ unexpand (void) if (convert) { - if (next_tab_column < column) - error (EXIT_FAILURE, 0, _("input line is too long")); - if (c == '\t') { column = next_tab_column;