* zgrep.in: If the file name contains newline, &, \, or |, escape
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 26 Nov 2006 20:48:29 +0000 (20:48 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 26 Nov 2006 20:48:29 +0000 (20:48 +0000)
the character so that 'sed' doesn't mishandle it as a replacement.
Problem reported by Bdale Garbee.

ChangeLog
zgrep.in

index c4fb67c2195101b4bad686a994198b5a37142d1b..78d6ebbf61387caaffb0290438bbc6dd4c0322c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-26  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * zgrep.in: If the file name contains newline, &, \, or |, escape
+       the character so that 'sed' doesn't mishandle it as a replacement.
+       Problem reported by Bdale Garbee.
+
 2006-11-25  Paul Eggert  <eggert@cs.ucla.edu>
 
        * gzip.1 (OPTIONS): ouput -> output.  Problem reported by Matt
index 01728838ecfc30c6427a19d55f36940d29e3090a..e309f0542e157c267237c7bcd91723b09d412788 100644 (file)
--- a/zgrep.in
+++ b/zgrep.in
@@ -116,10 +116,27 @@ for i do
     elif test $with_filename -eq 0 && { test $# -eq 1 || test $no_filename -eq 1; }; then
       $grep $opt "$pat"
     else
+      escaped=
+      while :; do
+       case $i in
+       *'
+'*)
+         char='
+'        repl='\\n';;
+       *'&'*) char='&' repl='\&';;
+       *'\'*) char='\\' repl='\\';;
+       *'|'*) char='|' repl='\|';;
+       *) break;;
+       esac
+       up_to_first_char="\\([^$char]*\\)"
+       after_first_char="[^$char]*$char\\(.*\\)"
+       escaped=$escaped`expr "X$i" : "X$up_to_first_char"`$repl
+       i=`expr "X$i" : "$after_first_char"`
+      done
       if test $with_filename -eq 1; then
-       sed_script="s|^[^:]*:|${i}:|"
+       sed_script="s|[^:]*|$escaped$i|"
       else
-       sed_script="s|^|${i}:|"
+       sed_script="s|^|$escaped$i:|"
       fi
 
       # Fail if either grep or sed fails.