>From 38e9a954ff5bda5c757596084536bff1db503432 Mon Sep 17 00:00:00 2001 From: Assaf Gordon Date: Thu, 18 Oct 2018 04:35:22 -0600 Subject: [PATCH] sed: reject r/R/w/W commands without a filename w/W (and s///w) commands Without a filename would print a confusing error message: $ sed w sed: couldn't open file : No such file or directory While r/R commands with empty file name were a silent no-op. With this change, sed programs with empty filename are rejected with a clear error: $ sed 's/1/2/w' sed: -e expression #1, char 7: missing filename in r/R/w/W commands $ sed r sed: -e expression #1, char 1: missing filename in r/R/w/W commands * NEWS: Mention change. * sed/compile.c (get_openfile): Exit with an error message if filename is missing. (compile_program): Same for 'r' command code. * testsuite/missing-filename.sh: New test. * testsuite/local.mk (T): Add new test. --- NEWS | 4 ++++ sed/compile.c | 10 +++++++++- testsuite/local.mk | 1 + testsuite/missing-filename.sh | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100755 testsuite/missing-filename.sh diff --git a/NEWS b/NEWS index e25d26b..db467aa 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,10 @@ GNU sed NEWS -*- outline -*- ** Improvements + sed now prints a clear error message when r/R/w/W (and s///w) commands + are missing a filename. Previously, w/W commands would fail with confusing + error message, while r/R would be a silent no-op. + sed now uses fully-buffered output (instead of line-buffered) when writing to files. This should noticeably improve performance of "sed -i" and other write commands. diff --git a/sed/compile.c b/sed/compile.c index 6776b65..184eeb3 100644 --- a/sed/compile.c +++ b/sed/compile.c @@ -139,7 +139,8 @@ static const char errors[] = "incomplete command\0" "\":\" lacks a label\0" "recursive escaping after \\c not allowed\0" - "e/r/w commands disabled in sandbox mode"; + "e/r/w commands disabled in sandbox mode\0" + "missing filename in r/R/w/W commands"; #define BAD_BANG (errors) #define BAD_COMMA (BAD_BANG + sizeof (N_("multiple `!'s"))) @@ -188,6 +189,8 @@ static const char errors[] = + sizeof (N_("\":\" lacks a label"))) #define DISALLOWED_CMD (RECURSIVE_ESCAPE_C \ + sizeof (N_("recursive escaping after \\c not allowed"))) +#define MISSING_FILENAME (DISALLOWED_CMD \ + + sizeof(N_( "e/r/w commands disabled in sandbox mode"))) /* #define END_ERRORS (DISALLOWED_CMD \ + sizeof(N_( "e/r/w commands disabled in sandbox mode"))) */ @@ -386,6 +389,9 @@ get_openfile (struct output **file_ptrs, const char *mode, int fail) b = read_filename (); file_name = get_buffer (b); + if (strlen (file_name) == 0) + bad_prog (_(MISSING_FILENAME)); + for (p=*file_ptrs; p; p=p->link) if (strcmp (p->name, file_name) == 0) break; @@ -1182,6 +1188,8 @@ compile_program (struct vector *vector) case 'r': b = read_filename (); + if (strlen (get_buffer (b)) == 0) + bad_prog (_(MISSING_FILENAME)); cur_cmd->x.fname = xstrdup (get_buffer (b)); free_buffer (b); break; diff --git a/testsuite/local.mk b/testsuite/local.mk index 6d0a74d..031df2e 100644 --- a/testsuite/local.mk +++ b/testsuite/local.mk @@ -64,6 +64,7 @@ T = \ testsuite/mb-charclass-non-utf8.sh \ testsuite/mb-match-slash.sh \ testsuite/mb-y-translate.sh \ + testsuite/missing-filename.sh \ testsuite/newline-dfa-bug.sh \ testsuite/normalize-text.sh \ testsuite/nulldata.sh \ diff --git a/testsuite/missing-filename.sh b/testsuite/missing-filename.sh new file mode 100755 index 0000000..704bc67 --- /dev/null +++ b/testsuite/missing-filename.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Test r/R/w/W commands without a file name. + +# Copyright (C) 2018 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +. "${srcdir=.}/testsuite/init.sh"; path_prepend_ ./sed +print_ver_ sed + +# Same error message, different character position in the sed program. +for i in 1 7 ; do + err="sed: -e expression #1, char $i: missing filename in r/R/w/W commands" + echo "$err" > exp-err$i || framework_failure_ +done + +# r/R/w/W commands +for cmd in r R w W ; do + returns_ 1 sed $cmd /dev/null 2>err1 || fail=1 + compare exp-err1 err1 || fail=1 +done + +returns_ 1 sed 's/1/2/w' /dev/null 2>err7 || fail=1 +compare exp-err7 err7 || fail=1 + +Exit $fail -- 2.11.0