libtool-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Libtool branch, master, updated. v2.2.6-17-g101ad44


From: Ralf Wildenhues
Subject: [SCM] GNU Libtool branch, master, updated. v2.2.6-17-g101ad44
Date: Tue, 11 Nov 2008 05:57:28 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Libtool".

The branch, master has been updated
       via  101ad44541c6d303cf465937a212042885f4338e (commit)
      from  0676af7c2a5e30993957dfd49e4e972d54426bfb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 101ad44541c6d303cf465937a212042885f4338e
Author: Bruno Haible <address@hidden>
Date:   Tue Nov 11 06:51:24 2008 +0100

    Fix cwrapper argument mangling on w32.
    
    * libltdl/config/ltmain.m4sh (func_emit_cwrapperexe_src): On
    mingw, preprocess the argument vector through prepare_spawn.
    * tests/execute-mode.at (execute mode): Output args
    newline-separated.  Extend tests by more argument pairs that
    contain special characters, where the w32 cwrapper fails.
    Also test a real compiled program, linked against an uninstalled
    library, to expose cwrapper issues.
    * NEWS: Update.
    
    Signed-off-by: Ralf Wildenhues <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                  |   13 +++++
 NEWS                       |    2 +
 libltdl/config/ltmain.m4sh |  120 ++++++++++++++++++++++++++++++++++++++++++++
 tests/execute-mode.at      |   91 ++++++++++++++++++++++++++++++++--
 4 files changed, 222 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2148a2c..1abce44 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-11-11  Bruno Haible  <address@hidden>
+           Ralf Wildenhues  <address@hidden>
+
+       Fix cwrapper argument mangling on w32.
+       * libltdl/config/ltmain.m4sh (func_emit_cwrapperexe_src): On
+       mingw, preprocess the argument vector through prepare_spawn.
+       * tests/execute-mode.at (execute mode): Output args
+       newline-separated.  Extend tests by more argument pairs that
+       contain special characters, where the w32 cwrapper fails.
+       Also test a real compiled program, linked against an uninstalled
+       library, to expose cwrapper issues.
+       * NEWS: Update.
+
 2008-11-10  Ralf Wildenhues  <address@hidden>
 
        Update to GFDL 1.3.
diff --git a/NEWS b/NEWS
index 4945c51..a38bfb3 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ New in 2.2.8 2008-??-??: git version 2.2.7a, Libtool team:
 
   - Fix 2.2.6 regression that prevented using the libltdl macros together
     with Autoconf 2.59 (`possibly undefined macro: LT_LIBEXT').
+  - Fix 2.2.4 regression that caused arguments with special characters
+    to be mangled by the compile wrapper for uninstalled programs on MinGW.
 
 * Miscellaneous changes:
 
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 005c6a8..e7a5ff0 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -2887,6 +2887,7 @@ void lt_opt_process_env_append (const char *arg);
 int lt_split_name_value (const char *arg, char** name, char** value);
 void lt_update_exe_path (const char *name, const char *value);
 void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
 
 static const char *script_text_part1 =
 EOF
@@ -3167,6 +3168,7 @@ EOF
              mingw*)
                cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
   rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
@@ -3630,8 +3632,126 @@ lt_update_lib_path (const char *name, const char *value)
     }
 }
 
+EOF
+           case $host_os in
+             mingw*)
+               cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ 
\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " 
\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+       new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+       {
+         int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+         size_t length;
+         unsigned int backslashes;
+         const char *s;
+         char *quoted_string;
+         char *p;
+
+         length = 0;
+         backslashes = 0;
+         if (quote_around)
+           length++;
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               length += backslashes + 1;
+             length++;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           length += backslashes + 1;
+
+         quoted_string = XMALLOC (char, length + 1);
 
+         p = quoted_string;
+         backslashes = 0;
+         if (quote_around)
+           *p++ = '"';
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               {
+                 unsigned int j;
+                 for (j = backslashes + 1; j > 0; j--)
+                   *p++ = '\\';
+               }
+             *p++ = c;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           {
+             unsigned int j;
+             for (j = backslashes; j > 0; j--)
+               *p++ = '\\';
+             *p++ = '"';
+           }
+         *p = '\0';
+
+         new_argv[i] = quoted_string;
+       }
+      else
+       new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
 EOF
+               ;;
+           esac
 }
 # end: func_emit_cwrapperexe_src
 
diff --git a/tests/execute-mode.at b/tests/execute-mode.at
index 349c829..acbe081 100644
--- a/tests/execute-mode.at
+++ b/tests/execute-mode.at
@@ -25,10 +25,15 @@
 AT_SETUP([execute mode])
 AT_KEYWORDS([libtool])
 
+eval `$LIBTOOL --config | $EGREP '^(FGREP)='`
+
 AT_DATA([foo],
 [[#! /bin/sh
 if test $# -gt 0; then
-  echo "$@"
+  for arg
+  do
+    printf %s\\n "$arg"
+  done
 else
   :
 fi
@@ -50,7 +55,10 @@ fi
 
 AT_DATA([lt-real],
 [[#! /bin/sh
-echo "$@"
+for arg
+do
+  printf %s\\n "$arg"
+done
 cat
 ]])
 
@@ -81,6 +89,45 @@ mkdir sub
 cp foo sub/foo
 chmod +x foo sub/foo lt-wrapper lt-real
 
+AT_DATA([liba.c],
+[[int a () { return 0; }
+]])
+
+AT_DATA([main.c],
+[[#include <stdio.h>
+extern int a ();
+int main (int argc, char **argv)
+{
+  int i;
+  for (i=1; i<argc; ++i)
+    {
+      if (i != 1)
+       fputc ('\n', stdout);
+      fputs (argv[i], stdout);
+    }
+  fputc ('\n', stdout);
+  return a ();
+}
+]])
+
+instdir=`pwd`/inst
+libdir=$instdir/lib
+
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c liba.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o liba.la -rpath $libdir 
liba.lo],
+        [], [ignore], [ignore])
+AT_CHECK([$CC $CPPFLAGS $CFLAGS -c main.c],
+        [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main main.$OBJEXT 
liba.la],
+        [], [ignore], [ignore])
+
+# end of preparatory blurb.
+# Now, when doing the tests, we both try the fake wrappers plus the real one
+# (only the latter exposes the C wrappers used for w32 systems).
+# With the latter, however, we need to ignore additional output; esp. wine
+# may be rather noisy.
+
 AT_CHECK([$LIBTOOL --mode=execute ./foo])
 AT_CHECK([$LIBTOOL --mode=execute sub/foo])
 AT_CHECK([$LIBTOOL --mode=execute ./foo foo], [], [foo
@@ -91,7 +138,9 @@ AT_CHECK([cd sub && $LIBTOOL --mode=execute ./foo ../foo], 
[], [../foo
 ])
 # suppose that ./foo is gdb, and lt-wrapper is the wrapper script.
 AT_CHECK([$LIBTOOL --mode=execute ./foo lt-wrapper bar baz </dev/null], [],
-        [./lt-real bar baz
+        [./lt-real
+bar
+baz
 ])
 
 # check that stdin works even with -dlopen.
@@ -116,7 +165,41 @@ AT_CHECK([$LIBTOOL --mode=execute ./lt-wrapper "arg  with 
special chars: \$!&*\`
         [], [arg  with special chars: $!&*`'()
 ])
 AT_CHECK([$LIBTOOL --mode=execute ./foo lt-wrapper "arg  with special chars: 
\$!&*\`'()"],
-        [], [./lt-real arg  with special chars: $!&*`'()
+        [], [./lt-real
+arg  with special chars: $!&*`'()
 ])
 
+# We always pair two args.  The first one is never the empty string.
+arg1=
+for arg2 in \
+   'def ghi' '' \
+   'd"e' 'f"g' \
+   'd\"e' 'f\"g' \
+   'd\\"e' 'f\\"g' \
+   'd\\\"e' 'f\\\"g' \
+   'd\' '' \
+   'd\\' '' \
+   'd\\\' '' \
+   'd\\\\' '' \
+   '<' '>' \
+   '<def>' ''
+do
+  if test -z "$arg1"; then
+    arg1=$arg2; continue
+  fi
+  AT_CHECK([$LIBTOOL --mode=execute ./foo abc "$arg1" "$arg2" xyz], [], 
[stdout])
+  AT_CHECK([$FGREP "$arg1" stdout], [], [ignore])
+  AT_CHECK([$FGREP "$arg2" stdout], [], [ignore])
+  AT_CHECK([test `sed -n '/^abc$/,/^xyz$/p' stdout | wc -l` -eq 4])
+  AT_CHECK([$LIBTOOL --mode=execute ./lt-wrapper abc "$arg1" "$arg2" xyz 
</dev/null], [], [stdout])
+  AT_CHECK([$FGREP "$arg1" stdout], [], [ignore])
+  AT_CHECK([$FGREP "$arg2" stdout], [], [ignore])
+  AT_CHECK([test `sed -n '/^abc$/,/^xyz$/p' stdout | wc -l` -eq 4])
+  AT_CHECK([$LIBTOOL --mode=execute ./foo lt-wrapper abc "$arg1" "$arg2" xyz], 
[], [stdout])
+  AT_CHECK([$FGREP "$arg1" stdout], [], [ignore])
+  AT_CHECK([$FGREP "$arg2" stdout], [], [ignore])
+  AT_CHECK([test `sed -n '/^abc$/,/^xyz$/p' stdout | wc -l` -eq 4])
+  arg1=
+done
+
 AT_CLEANUP


hooks/post-receive
--
GNU Libtool




reply via email to

[Prev in Thread] Current Thread [Next in Thread]