OSDN Git Service

The perl build's attempt to escape spaces and such in LD_LIBRARY_PATH is _SAD_.
authorRob Landley <rob@landley.net>
Thu, 18 Feb 2016 01:21:44 +0000 (19:21 -0600)
committerRob Landley <rob@landley.net>
Thu, 18 Feb 2016 01:21:44 +0000 (19:21 -0600)
It uses a sed expression that assumes you can escape - to use it as a literal
(you can't, it has to be first or last char of the range), and assumes
you have to escape delimiters in sed [] context (you don't), and/or that
non-printf escapes become the literal character (they don't, the backslash
is preserved as a literal), meaning it winds up doing "s/[\-\]//" which is
a length 1 range, which is officially undefined behavior according to posix,
and regcomp errors out.

But if we don't accept it (like other implementations do) the perl build
breaks. So collapse [A-A] into just [A].

Testcae taken from perl 5.22.0 file Makefile.SH line 8.

(While we're at it, remove an unused argument from a function.)

tests/sed.test
toys/posix/sed.c

index eff2306..c62f9c4 100755 (executable)
@@ -131,10 +131,13 @@ hello'" "merp\nhello\n" "" "merp"
 
 testing "" "sed -e '/x/c\' -e 'y'" 'y\n' '' 'x\n'
 testing "" "sed -e 's/a[([]*b/X/'" 'X' '' 'a[(b'
+testing "" "sed 'y/a\\bc/de\f/'" "db\f" "" "abc"
+testing "sed [a-a] (for perl)" "sed '"'s/\([^a-zA-Z0-9.:_\-\/]\)/\\\1/g'"'" \
+  'he\ llo' "" "he llo"
 
 # You have to match the first line of a range in order to activate
 # the range, numeric and ascii work the same way
-testing "skip start of range" "sed -e n -e '1,2s/b/c/'" "a\nb\n" "" "a\nb\n"
+testing "sed skip start of range" "sed -e n -e '1,2s/b/c/'" "a\nb\n" "" "a\nb\n"
 
 #echo meep | sed/sed -e '1a\' -e 'huh'
 #echo blah | sed/sed -f <(echo -e "1a\\\\\nboom")
@@ -146,4 +149,5 @@ testing "sed bonus backslashes" \
   "hello\nl x\nab\nc\n" "" "hello\n"
 # -i with $ last line test
 
+
 exit $FAILCOUNT
index 013dc6b..9b5e666 100644 (file)
@@ -701,7 +701,7 @@ static void do_sed(int fd, char *name)
 // returns processed copy of string (0 if error), *pstr advances to next
 // unused char. if delim (or *delim) is 0 uses/saves starting char as delimiter
 // if regxex, ignore delimiter in [ranges]
-static char *unescape_delimited_string(char **pstr, char *delim, int regex)
+static char *unescape_delimited_string(char **pstr, char *delim)
 {
   char *to, *from, mode = 0, d;
 
@@ -720,9 +720,14 @@ static char *unescape_delimited_string(char **pstr, char *delim, int regex)
     // delimiter in regex character range doesn't count
     if (!mode && *from == '[') {
       mode = '[';
-      if (from[1] == ']') *(to++) = *(from++);
+      if (from[1]=='-' || from[1]==']') *(to++) = *(from++);
     } else if (mode && *from == ']') mode = 0;
-    else if (*from == '\\') {
+    // Length 1 range (X-X with same X) is "undefined" and makes regcomp err,
+    // but the perl build does it, so we need to filter it out.
+    else if (mode && *from == '-' && from[-1] == from[1]) {
+      from+=2;
+      continue;
+    } else if (*from == '\\') {
       if (!from[1]) return 0;
 
       // Check escaped end delimiter before printf style escapes.
@@ -735,7 +740,7 @@ static char *unescape_delimited_string(char **pstr, char *delim, int regex)
           *(to++) = c;
           from+=2;
           continue;
-        } else *(to++) = *(from++);
+        } else if (!mode) *(to++) = *(from++);
       }
     }
     *(to++) = *(from++);
@@ -802,7 +807,7 @@ static void jewel_of_judgement(char **pline, long len)
       } else if (*line == '/' || *line == '\\') {
         char *s = line;
 
-        if (!(s = unescape_delimited_string(&line, 0, 1))) goto brand;
+        if (!(s = unescape_delimited_string(&line, 0))) goto brand;
         if (!*s) corwin->rmatch[i] = 0;
         else {
           xregcomp((void *)reg, s, (toys.optflags & FLAG_r)*REG_EXTENDED);
@@ -844,7 +849,7 @@ static void jewel_of_judgement(char **pline, long len)
 
       // get pattern (just record, we parse it later)
       corwin->arg2 = reg - (char *)corwin;
-      if (!(TT.remember = unescape_delimited_string(&line, &delim, 1)))
+      if (!(TT.remember = unescape_delimited_string(&line, &delim)))
         goto brand;
 
       reg += sizeof(regex_t);
@@ -940,13 +945,13 @@ writenow:
       char *s, delim = 0;
       int len;
 
-      if (!(s = unescape_delimited_string(&line, &delim, 0))) goto brand;
+      if (!(s = unescape_delimited_string(&line, &delim))) goto brand;
       corwin->arg1 = reg-(char *)corwin;
       len = strlen(s);
       reg = extend_string((void *)&corwin, s, reg-(char *)corwin, len);
       free(s);
       corwin->arg2 = reg-(char *)corwin;
-      if (!(s = unescape_delimited_string(&line, &delim, 0))) goto brand;
+      if (!(s = unescape_delimited_string(&line, &delim))) goto brand;
       if (len != strlen(s)) goto brand;
       reg = extend_string((void *)&corwin, s, reg-(char*)corwin, len);
       free(s);