Bug#754057: perl: erroneous quoting in Makefile.SH

Niko Tyni ntyni at debian.org
Wed Apr 15 19:49:31 UTC 2015


On Mon, Jul 07, 2014 at 09:30:20AM +0300, Niko Tyni wrote:

>  echo "$1" | sed 's/\([^a-zA-Z0-9.:_\-\/]\)/\\\1/g' ;;
> 
> should possibly be
> 
>  echo "$1" | sed 's/\([^a-zA-Z0-9.:_\/-]\)/\\\1/g' ;;

(My, what a mess.)

To expand on this a bit, the (GNU) sed manual states
in the 'Regular Expressions' chapter:

  to include `-' in the list, make it the first or last

and

  The characters `$', `*', `.', `[', and `\' are normally not special
  within LIST.  For example, `[\*]' matches either `\' or `*', because the
  `\' is not special here.

The forward slash ('/') should be an exception here because it's the
delimiter; from the chapter 'The "s" Command':

  The `/' character (or whatever other character is used in its stead)
  can appear in the REGEXP or REPLACEMENT only if it is preceded by a `\'
  character.

However, it looks like this doesn't apply to character lists inside
the regexp at all [1].  This seems like a possible bug in the sed
documentation.

So sed 's/\([^a-zA-Z0-9.:_\-\/]\)/\\\1/g' quotes characters that are
 - not alphanumeric (a-zA-Z0-9)
 - not one of '.', ':', or '_'
 - not in the range \-\, i.e. not '\'
 - not '/'

while the suggested 's/\([^a-zA-Z0-9.:_\/-]\)/\\\1/g'
would quote characters that are

 - not alphanumeric
 - not one of '.', ':', '_', '\', '/', or '-'

which is probably what was intended here.

This is still relying on the delimiter having no special meaning inside
a character list. I'm not sure how portable alternative delimiters are;
if they are an option here an even better solution would be
  's|\([^a-zA-Z0-9.:_\/-]\)|\\\1|g'


[1] sed 's/[/]//g' is accepted and removes all forward slashes;
    sed 's/[^/]//g' is also accepted and removes everything but forward slashes
-- 
Niko Tyni   ntyni at debian.org




More information about the Perl-maintainers mailing list