Bug 1124436 - libtool wrapper corrupts command line on Windows
Summary: libtool wrapper corrupts command line on Windows
Keywords:
Status: ASSIGNED
Alias: None
Product: Fedora
Classification: Fedora
Component: libtool
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Patrik Novotný
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2014-07-29 13:36 UTC by David Woodhouse
Modified: 2019-03-13 17:39 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: Enhancement
Doc Text:
Clone Of:
Environment:
Last Closed:


Attachments (Terms of Use)
reproducer (312.75 KB, application/gzip)
2014-07-30 08:19 UTC, Pavel Raiskup
no flags Details

Description David Woodhouse 2014-07-29 13:36:26 UTC
On Windows, you can spawn a program using arbitrary Unicode characters in its command line.

The arguments seen by the main() function in the argv[] array will have any characters outside the native code page replaced with '?'.

A process can still see the original full command line, though, by using the GetCommandLineW() function.

Unfortunately, the libtool wrapper does not preserve the original command line, and spawns the actual executable from the .libs directory with the out-of-codepage characters replaced by '?'.

The wrapper should use GetcommandLineW() and pass the *original* arguments, not the sanitised ones from argv[].

Test case (which works when invoked directly but fails when invoked via libtool wrapper):

#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	HANDLE stdout_h = GetStdHandle(STD_OUTPUT_HANDLE);
	wchar_t *str;

	if (argc < 2) {
		printf("Need an argument\n");
		return 1;
	}

	printf("argv[1] is '%s'\n", argv[1]);

	str = GetCommandLineW();

	WriteConsoleW(stdout_h, str, wcslen(str), NULL, NULL);
	printf("\n");
	return 0;
} 

This is easily testable using mingw and wine.

Comment 1 Pavel Raiskup 2014-07-30 06:42:39 UTC
David, thanks for the report.

(In reply to David Woodhouse from comment #0)
> On Windows, you can spawn a program using arbitrary Unicode characters in
> its command line.
> 
> The arguments seen by the main() function in the argv[] array will have any
> characters outside the native code page replaced with '?'.
> 
> A process can still see the original full command line, though, by using the
> GetCommandLineW() function.
> 
> Unfortunately, the libtool wrapper does not preserve the original command
> line, and spawns the actual executable from the .libs directory with the
> out-of-codepage characters replaced by '?'.
> 
> The wrapper should use GetcommandLineW() and pass the *original* arguments,
> not the sanitised ones from argv[].

This bugfix request should definitely go to upstream [1].  When talking about
libtool wrapper on Windows, we are talking most likely about _development on_
Windows (not cross-platform development on linux for windows) - and that is
somewhat out of scope Fedora.  I'm hardly able to test it (I have no
Windows box atm, sorry).  Yep, wine ...

> Test case (which works when invoked directly but fails when invoked via
> libtool wrapper):

... but that ^^ does not seem to be truth, without libtool wrapper it does not
work for me (though I am not sure what is behind):

  $ i686-w64-mingw32-gcc main.c
  $ wine ./a.exe "Žluťoučký"
  argv[1] is 'ÄluŁouŔkř'
  Z:\home\praiskup\rh\projects\tcsh\a.exe Žluťoučk

Probably more self-standing example including 'Makefile.am' & 'configure.ac'
together with step-by-step intro would be useful in case of such reports.

[1] http://www.gnu.org/software/libtool/manual/html_node/Reporting-bugs.html

Pavel

Comment 2 Pavel Raiskup 2014-07-30 08:19:56 UTC
Created attachment 922455 [details]
reproducer

David, I'm curious enough - is that your issue:

$ tar -xf windows-cross-compilation*
$ cd windows-cross-compilation-1.1
$ ./configure --host=i686-w64-mingw32
$ make
$ ./src/hello.exe "Příliš Žluťoučký Kůň"
argv[1] is 'PrφliÜ Älutouck² Kun'
Z:/tmp/windows-cross-compilation-1.1/src/.libs/hello.exe "Príliš Žlutoucký Kun"
$ ./src/.libs/hello.exe "Příliš Žluťoučký Kůň"
argv[1] is 'PrφliÜ Älutouck² Kun'
Z:\tmp\windows-cross-compilation-1.1\src\.libs\hello.exe "Příliš Žluťoučký Kůň"

Comment 3 David Woodhouse 2014-07-30 10:17:47 UTC
Yes.

[dwoodhou@i7 windows-cross-compilation-1.1]$ src/hello.exe ♥
argv[1] is '?'
Z:/home/dwmw2/Downloads/windows-cross-compilation-1.1/src/.libs/hello.exe ?
[dwoodhou@i7 windows-cross-compilation-1.1]$ src/.libs/hello.exe ♥
argv[1] is '?'
Z:\home\dwmw2\Downloads\windows-cross-compilation-1.1\src\.libs\hello.exe ♥
[dwoodhou@i7 windows-cross-compilation-1.1]$

Comment 4 David Woodhouse 2014-07-30 10:24:14 UTC
Thanks for taking the time to produce the test case, btw. As for cross-building for Windows being out of scope for Fedora, the MinGW SIG may not entirely agree with you there :)

I've added their list to Cc.

Comment 5 Pavel Raiskup 2014-07-30 10:38:48 UTC
(In reply to David Woodhouse from comment #4)
> As for cross-building for Windows being out of scope for Fedora

I'm not familiar with this use-case, I need to look at it more carefully TBH.
But I thought that the binary libtool wrapper is not installed -- so it would
be low prio issue as we mail live without that.  But that may have been pretty
likely untrue?

Comment 6 Richard W.M. Jones 2014-07-30 10:43:02 UTC
sudo yum install mingw32-gcc
mingw32-configure
make
wine program.exe

.. works, on Fedora, for many libraries and programs.

Comment 7 David Woodhouse 2014-07-30 11:05:59 UTC
You're correct that we don't *install* the binary libtool wrapper.

Whether building natively, or building with MinGW, the wrapper is only used for running the program locally inside the build tree.

When developing software, this is useful — you make a change, you build and you run it from the build tree to test it.

The MinGW support on Fedora is extremely useful — I can have build trees for Linux and for Windows side by side, and test my changes in both environments (mostly using Wine, and then occasionally actually testing on real Windows too).

But when I was adding full UTF16 command line handling for Windows, the Fedora MinGW setup failed me because of this bug. I *had* to test every little change on real Windows, which is a PITA. At least until I realised it wasn't a wine bug, and I could work around it :)

Comment 8 Pavel Raiskup 2014-08-26 14:18:34 UTC
Ok, I'm little bit closer to the problem, probably.  I'm not familiar with
windows, so I'm not sure.  Looking at the GetcommandLineW from comment #1
is not a way to go, I would say, because it does not preserve arguments with
spaces like './test.exe "arg a" arg_b' to be parsed later.

What we would need is to switch from 'main' to 'wmain' and use -municode.
Dunno how portable that is, probably we could use it when we are allowed to
(hidden behind some #ifdef/configure checks).  Argv from wmain may then be
passed to _wspawnv instead of _spawnv (as is done in libtool wrapper now).

Any ideas?

Comment 9 David Woodhouse 2014-08-27 09:45:42 UTC
(In reply to Pavel Raiskup from comment #8)
> Ok, I'm little bit closer to the problem, probably.  I'm not familiar with
> windows, so I'm not sure.  Looking at the GetcommandLineW from comment #1
> is not a way to go, I would say, because it does not preserve arguments with
> spaces like './test.exe "arg a" arg_b' to be parsed later.

Que?


#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	HANDLE stdout_h = GetStdHandle(STD_OUTPUT_HANDLE);
	wchar_t **argv_w;
	wchar_t *str;

	if (argc < 2) {
		printf("Need an argument\n");
		return 1;
	}

	printf("argc %d, argv[1] is '%s'\n", argc, argv[1]);

	str = GetCommandLineW();
	argv_w = CommandLineToArgvW(str, &argc);
	printf("argc_w %d, argv_w[1] is '", argc);
	WriteConsoleW(stdout_h, argv_w[1], wcslen(argv_w[1]), NULL, NULL);
	printf("'\n");
	return 0;
} 
[dwoodhou@i7 ~]$ $ wine foo.exe "foo♥ bar"
argc 2, argv[1] is 'foo? bar'
argc_w 2, argv_w[1] is 'foo♥ bar'

Comment 10 Pavel Raiskup 2014-08-27 10:08:35 UTC
(In reply to David Woodhouse from comment #9)
> (In reply to Pavel Raiskup from comment #8)
> > Looking at the GetcommandLineW from comment #1 is not a way to go, I would
> > say, because it does not preserve arguments with spaces like './test.exe
> > "arg a" arg_b' to be parsed later.
> 
> Que?

Argh, I missed the LPWSTR hides something more then wchar_t.  Thanks!

Comment 11 Pavel Raiskup 2014-09-12 08:30:19 UTC
Raised upstream bug, better to discuss/fix there:
http://news.gmane.org/gmane.comp.gnu.libtool.bugs

Comment 12 Pavel Raiskup 2014-09-12 08:33:03 UTC
Better link:
http://article.gmane.org/gmane.comp.gnu.libtool.bugs/8300

Comment 13 Fedora End Of Life 2015-05-29 12:30:22 UTC
This message is a reminder that Fedora 20 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 20. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '20'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 20 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

Comment 14 Fedora End Of Life 2015-11-04 15:31:36 UTC
This message is a reminder that Fedora 21 is nearing its end of life.
Approximately 4 (four) weeks from now Fedora will stop maintaining
and issuing updates for Fedora 21. It is Fedora's policy to close all
bug reports from releases that are no longer maintained. At that time
this bug will be closed as EOL if it remains open with a Fedora  'version'
of '21'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, simply change the 'version' 
to a later Fedora version.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora 21 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora, you are encouraged  change the 'version' to a later Fedora 
version prior this bug is closed as described in the policy above.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events. Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.


Note You need to log in before you can comment on or make changes to this bug.