diff --git a/ChangeLog b/ChangeLog index 043c5ab..4e84d8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2015-05-21 Bruce Korb + + * src/uudecode.c (decode): be more careful in guarding against + pathological "begin" lines + +2015-05-20 Filipe Brandenburger + Bruce Korb + Paul Eggert + + * src/local.h.git: Replace the no longer needed f{read,write}only_mode + with #defines for FOPEN_BINARY/FOPEN_TEXT a la emacs + * src/shar.c: Use these instead of trying to derive via autoconf. + * configure.ac.git: Drop the check for popen with "rb" mode. + 2015-01-06 Eric Blake build: avoid error message failure on 64-bit hosts diff --git a/configure.ac.git b/configure.ac.git index 6ab67d9..a669db0 100644 --- a/configure.ac.git +++ b/configure.ac.git @@ -94,12 +94,6 @@ AM_WITH_DMALLOC CATALOGS="$new_CATALOGS" fi] -AC_RUN_IFELSE( - [AC_LANG_PROGRAM([], [dnl - FILE * fp = popen ("date", "rb"); - exit (fp == NULL);])], - [AC_DEFINE([BINARY_MODE_POPEN], [1], [define if popen supports "rb" mode])] -) # INVOKE_LIBOPTS_MACROS INVOKE_LIBOPTS_MACROS diff --git a/src/local.h.git b/src/local.h.git index 8f234cb..14a3db9 100644 --- a/src/local.h.git +++ b/src/local.h.git @@ -22,14 +22,16 @@ INCLUDE-LIST -#ifdef SHAR_C -# ifdef BINARY_MODE_POPEN -static char const freadonly_mode[] = "rb"; -static char const fwriteonly_mode[] = "wb"; -# else -static char const freadonly_mode[] = "r"; -static char const fwriteonly_mode[] = "w"; -# endif +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +#if O_BINARY +# define FOPEN_BINARY "b" +# define FOPEN_TEXT "t" +#else +# define FOPEN_BINARY "" +# define FOPEN_TEXT "" #endif #endif /* SHARUTILS_LOCAL_H */ diff --git a/src/shar.c b/src/shar.c index 5507b3b..2524d3d 100644 --- a/src/shar.c +++ b/src/shar.c @@ -1170,7 +1170,7 @@ file_needs_encoding (char const * fname) average file size, even reading the whole file (if it is text) would usually be faster than invoking 'file'. */ - infp = fopen (fname, freadonly_mode); + infp = fopen (fname, "r" FOPEN_BINARY); if (infp == NULL) { @@ -1265,11 +1265,11 @@ encode_file_to_pipe ( { sprintf (cmdline, cmpr_state->cmpr_cmd_fmt, cmpr_state->cmpr_level, q_local_name); - in_fp = popen (cmdline, freadonly_mode); + in_fp = popen (cmdline, "r" FOPEN_BINARY); } else { - in_fp = fopen (local_name, freadonly_mode); + in_fp = fopen (local_name, "r" FOPEN_BINARY); open_fmt = "fopen"; open_txt = local_name; } @@ -1277,7 +1277,7 @@ encode_file_to_pipe ( if (in_fp == NULL) fserr (SHAR_EXIT_FAILED, open_fmt, open_txt); - out_fp = fdopen (out_fd, fwriteonly_mode); + out_fp = fdopen (out_fd, "w" FOPEN_BINARY); fprintf (out_fp, mode_fmt_z, restore_name); @@ -1321,7 +1321,7 @@ open_encoded_file (char const * local_name, char const * q_local_name, close (pipex[1]); { - FILE * fp = fdopen (pipex[0], freadonly_mode); + FILE * fp = fdopen (pipex[0], "r" FOPEN_BINARY); if (fp == NULL) fserr (SHAR_EXIT_FAILED, "fdopen", _("pipe fd")); return fp; @@ -1402,12 +1402,12 @@ open_encoded_file (char const * local_name, sprintf (p, uu_cmd_fmt, restore_name); } - /* Don't use freadonly_mode because it might be "rb", while we need + /* Don't use "r" FOPEN_BINARY mode because it might be "rb", while we need text-mode read here, because we will be reading pure text from uuencode, and we want to drop any CR characters from the CRLF line endings, when we write the result into the shar. */ { - FILE * in_fp = popen (cmdline, "r"); + FILE * in_fp = popen (cmdline, "r" TEXT_MODE); if (in_fp == NULL) fserr (SHAR_EXIT_FAILED, "popen", cmdline); @@ -1441,7 +1441,7 @@ open_shar_input ( *file_type_p = _("text"); *file_type_remote_p = SM_type_text; - infp = fopen (local_name, freadonly_mode); + infp = fopen (local_name, "r" FOPEN_BINARY); if (infp == NULL) fserr (SHAR_EXIT_FAILED, "fopen", local_name); *pipe_p = 0; @@ -1822,7 +1822,7 @@ finish_sharing_file (const char * lname, const char * lname_q, echo_status ("test $? -ne 0", SM_restore_failed, NULL, rname, 0); if ( ! HAVE_OPT(NO_MD5_DIGEST) - && (fp = fopen (lname, freadonly_mode)) != NULL + && (fp = fopen (lname, "r" FOPEN_BINARY)) != NULL && md5_stream (fp, md5buffer) == 0) { /* Validate the transferred file using 'md5sum' command. */ @@ -2050,7 +2050,7 @@ open_output (void) if (output_filename == NULL) parse_output_base_name (OPT_ARG(OUTPUT_PREFIX)); sprintf (output_filename, OPT_ARG(OUTPUT_PREFIX), ++part_number); - output = fopen (output_filename, fwriteonly_mode); + output = fopen (output_filename, "w" FOPEN_BINARY); if (output == NULL) fserr (SHAR_EXIT_FAILED, _("Opening"), output_filename); @@ -2152,7 +2152,7 @@ configure_shar (int * argc_p, char *** argv_p) * Redirect stderr to /dev/null in that case so that * the results are not cluttered with chatter. */ - FILE * fp = freopen ("/dev/null", fwriteonly_mode, stderr); + FILE * fp = freopen ("/dev/null", "w" FOPEN_BINARY, stderr); if (fp != stderr) error (SHAR_EXIT_FAILED, errno, _("reopening stderr to /dev/null")); diff --git a/src/uudecode.c b/src/uudecode.c index 9213cc4..1cfa1ec 100644 --- a/src/uudecode.c +++ b/src/uudecode.c @@ -63,6 +63,9 @@ static char const cright_years_z[] = #ifndef _ # define _(str) (str) #endif +#ifndef NL +#define NL '\n' +#endif /*=====================================================================\ | uudecode [FILE ...] | @@ -157,11 +160,11 @@ read_stduu (char const * inname, char const * outname) if (buf[0] != 'e') break; if (buf[1] != 'n') break; if (buf[2] != 'd') break; - if (buf[3] == '\n') + if (buf[3] == NL) return UUDECODE_EXIT_SUCCESS; if (buf[3] != '\r') break; - if (buf[4] == '\n') + if (buf[4] == NL) return UUDECODE_EXIT_SUCCESS; } while (0); @@ -384,14 +387,25 @@ decode (char const * inname) _("%s: Invalid or missing 'begin' line\n"), inname); } + if (strchr (buf, NL) == NULL) + goto bad_beginning; + if (strncmp (buf, "begin", 5) == 0) { char * scan = buf+5; - if (*scan == '-') + + check_begin_option: + + switch (*scan) { + default: + goto bad_beginning; + case ' ': + break; + case '-': { static char const base64[] = "ase64"; static char const encoded[] = "encoded"; - check_begin_option: + if (*++scan == 'b') { if (strncmp (scan+1, base64, sizeof (base64) - 1) != 0) @@ -411,12 +425,9 @@ decode (char const * inname) scan += sizeof (encoded) - 1; /* 'e' is included */ } - switch (*scan) { - case ' ': break; /* no more begin options */ - case '-': goto check_begin_option; - default: goto bad_beginning; - } + goto check_begin_option; } + } if (sscanf (scan, " %o %[^\n]", &mode, buf) == 2) break;