From: Thomas Weißschuh Date: Sat, 13 Apr 2024 08:34:32 +0000 (+0200) Subject: textutils: introduce and use fgetwc_or_err X-Git-Tag: v2.42-start~403^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12707a4948c1bcd54859824b26a46f530f0949d0;p=thirdparty%2Futil-linux.git textutils: introduce and use fgetwc_or_err A return value of WEOF of fgetwc() can either mean end-of-file or an error in errno. The error was ignored and interpreted as end-of-file. Introduce a new helper that aborts on error and use it in text-utils. This replaces all calls to plain fgetwc(). Closes #2909 Signed-off-by: Thomas Weißschuh --- diff --git a/include/Makemodule.am b/include/Makemodule.am index 50a8546128..bdf87e2213 100644 --- a/include/Makemodule.am +++ b/include/Makemodule.am @@ -26,6 +26,7 @@ dist_noinst_HEADERS += \ include/env.h \ include/exec_shell.h \ include/exitcodes.h \ + include/fgetwc_or_err.h \ include/fileeq.h \ include/fileutils.h \ include/fuzz.h \ diff --git a/include/fgetwc_or_err.h b/include/fgetwc_or_err.h new file mode 100644 index 0000000000..3cf9262834 --- /dev/null +++ b/include/fgetwc_or_err.h @@ -0,0 +1,23 @@ +#ifndef UTIL_LINUX_FGETWC_OR_ERR_H +#define UTIL_LINUX_FGETWC_OR_ERR_H + +#include +#include +#include + +#include "widechar.h" +#include "c.h" +#include "nls.h" + +static inline wint_t fgetwc_or_err(FILE *stream) { + wint_t ret; + + errno = 0; + ret = fgetwc(stream); + if (ret == WEOF && errno != 0) + err(EXIT_FAILURE, _("fgetwc() failed")); + + return ret; +} + +#endif /* _FGETWC_OR_ERR_H */ diff --git a/tests/expected/colcrt/regressions-crash1 b/tests/expected/colcrt/regressions-crash1 index 67a7b1c998..3b41a79524 100644 --- a/tests/expected/colcrt/regressions-crash1 +++ b/tests/expected/colcrt/regressions-crash1 @@ -1,2 +1 @@ - W U; U; D f U; D f D f > @W ]~ K- - ---- -- -- - -- -- ---- -- ---- -- - -- --- -- -return value: 0 +return value: 1 diff --git a/tests/expected/colcrt/regressions-crash1.err b/tests/expected/colcrt/regressions-crash1.err new file mode 100644 index 0000000000..5837df340c --- /dev/null +++ b/tests/expected/colcrt/regressions-crash1.err @@ -0,0 +1 @@ +colcrt: fgetwc() failed: Invalid or incomplete multibyte or wide character diff --git a/tests/expected/colcrt/regressions-crash2 b/tests/expected/colcrt/regressions-crash2 index 11ebf74a8f..58a43173eb 100644 --- a/tests/expected/colcrt/regressions-crash2 +++ b/tests/expected/colcrt/regressions-crash2 @@ -7,4 +7,4 @@ MN MN9| XYZ nT RnTUV| NXP:w - -MNOP.return value: 0 +return value: 1 diff --git a/tests/expected/colcrt/regressions-crash2.err b/tests/expected/colcrt/regressions-crash2.err new file mode 100644 index 0000000000..5837df340c --- /dev/null +++ b/tests/expected/colcrt/regressions-crash2.err @@ -0,0 +1 @@ +colcrt: fgetwc() failed: Invalid or incomplete multibyte or wide character diff --git a/tests/expected/colcrt/regressions-hang1 b/tests/expected/colcrt/regressions-hang1 index cb16e46a34..78fb568e5b 100644 --- a/tests/expected/colcrt/regressions-hang1 +++ b/tests/expected/colcrt/regressions-hang1 @@ -1,3 +1,3 @@ 789:;<=>=>?IABUVNXYZ[ `abcdefgg !"#$%&'()*+,-./01234)*:,-./0123456789:;[=>?1234)*:,-./0123456789:;[=>?4456789:;<=>?IABUVN`abcdefg !" - -return value: 0 +return value: 1 diff --git a/tests/expected/colcrt/regressions-hang1.err b/tests/expected/colcrt/regressions-hang1.err new file mode 100644 index 0000000000..5837df340c --- /dev/null +++ b/tests/expected/colcrt/regressions-hang1.err @@ -0,0 +1 @@ +colcrt: fgetwc() failed: Invalid or incomplete multibyte or wide character diff --git a/tests/ts/colcrt/regressions b/tests/ts/colcrt/regressions index 7bbba658be..2bb846959a 100755 --- a/tests/ts/colcrt/regressions +++ b/tests/ts/colcrt/regressions @@ -28,6 +28,7 @@ check_input_file() { ts_init_subtest ${1##*/} timeout 2 env LC_ALL=C.UTF-8 $TS_CMD_COLCRT < $1 >> $TS_OUTPUT 2>> $TS_ERRLOG echo "return value: $?" >> $TS_OUTPUT + sed -i -e 's/Illegal byte sequence/Invalid or incomplete multibyte or wide character/' $TS_ERRLOG ts_finalize_subtest } diff --git a/text-utils/colcrt.c b/text-utils/colcrt.c index 44d2c8a8c8..4a1214cc80 100644 --- a/text-utils/colcrt.c +++ b/text-utils/colcrt.c @@ -49,6 +49,7 @@ #include "c.h" #include "widechar.h" #include "closestream.h" +#include "fgetwc_or_err.h" /* * colcrt - replaces col for crts with new nroff esp. when using tbl. @@ -164,7 +165,7 @@ static void colcrt(struct colcrt_control *ctl) errno = 0; old_pos = ftell(ctl->f); - while (fgetwc(ctl->f) != L'\n') { + while (fgetwc_or_err(ctl->f) != L'\n') { long new_pos; if (ferror(ctl->f) || feof(ctl->f)) @@ -179,10 +180,10 @@ static void colcrt(struct colcrt_control *ctl) col = -1; continue; } - c = fgetwc(ctl->f); + c = fgetwc_or_err(ctl->f); switch (c) { case 033: /* ESC */ - c = fgetwc(ctl->f); + c = fgetwc_or_err(ctl->f); if (c == L'8') { col = rubchars(ctl, col, 1); continue; diff --git a/text-utils/colrm.c b/text-utils/colrm.c index d893137164..363d732b62 100644 --- a/text-utils/colrm.c +++ b/text-utils/colrm.c @@ -48,6 +48,7 @@ #include "c.h" #include "widechar.h" #include "closestream.h" +#include "fgetwc_or_err.h" /* COLRM removes unwanted columns from a file @@ -81,7 +82,7 @@ static int process_input(unsigned long first, unsigned long last) int padding; for (;;) { - c = fgetwc(stdin); + c = fgetwc_or_err(stdin); if (c == WEOF) return 0; if (c == '\t') @@ -112,7 +113,7 @@ static int process_input(unsigned long first, unsigned long last) /* Loop getting rid of characters */ while (!last || ct < last) { - c = fgetwc(stdin); + c = fgetwc_or_err(stdin); if (c == WEOF) return 0; if (c == '\n') { @@ -135,7 +136,7 @@ static int process_input(unsigned long first, unsigned long last) /* Output last of the line */ for (;;) { - c = fgetwc(stdin); + c = fgetwc_or_err(stdin); if (c == WEOF) break; if (c == '\n') { diff --git a/text-utils/rev.c b/text-utils/rev.c index 4b731890d8..fc7ac6203b 100644 --- a/text-utils/rev.c +++ b/text-utils/rev.c @@ -63,6 +63,7 @@ #include "widechar.h" #include "c.h" #include "closestream.h" +#include "fgetwc_or_err.h" static void sig_handler(int signo __attribute__ ((__unused__))) { @@ -100,7 +101,7 @@ static size_t read_line(wchar_t sep, wchar_t *str, size_t n, FILE *stream) { size_t r = 0; while (r < n) { - wint_t c = fgetwc(stream); + wint_t c = fgetwc_or_err(stream); if (c == WEOF) break; str[r++] = c; diff --git a/text-utils/ul.c b/text-utils/ul.c index 1df4642eb3..62bfcd7bf9 100644 --- a/text-utils/ul.c +++ b/text-utils/ul.c @@ -62,6 +62,7 @@ #include "widechar.h" #include "c.h" #include "closestream.h" +#include "fgetwc_or_err.h" #define ESC '\033' #define SO '\016' @@ -439,7 +440,7 @@ static int handle_escape(struct ul_ctl *ctl, struct term_caps const *const tcs, { wint_t c; - switch (c = fgetwc(f)) { + switch (c = fgetwc_or_err(f)) { case HREV: if (0 < ctl->half_position) { ctl->mode &= ~SUBSCRIPT; @@ -479,7 +480,7 @@ static void filter(struct ul_ctl *ctl, struct term_caps const *const tcs, FILE * wint_t c; int i, width; - while ((c = fgetwc(f)) != WEOF) { + while ((c = fgetwc_or_err(f)) != WEOF) { switch (c) { case '\b': set_column(ctl, ctl->column && 0 < ctl->column ? ctl->column - 1 : 0); @@ -498,7 +499,7 @@ static void filter(struct ul_ctl *ctl, struct term_caps const *const tcs, FILE * continue; case ESC: if (handle_escape(ctl, tcs, f)) { - c = fgetwc(f); + c = fgetwc_or_err(f); errx(EXIT_FAILURE, _("unknown escape sequence in input: %o, %o"), ESC, c); }