Skip Menu |

This queue is for tickets about the Win32-ShellQuote CPAN distribution.

Report information
The Basics
Id: 130905
Status: rejected
Priority: 0/
Queue: Win32-ShellQuote

People
Owner: Nobody in particular
Requestors: Chris.Denley [...] experian.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Date: Tue, 5 Nov 2019 18:29:26 +0000
Subject: ^ quote_system_string 2>&1
To: "bug-Win32-ShellQuote [...] rt.cpan.org" <bug-Win32-ShellQuote [...] rt.cpan.org>
From: "Denley, Chris" <Chris.Denley [...] experian.com>
Not sure if this is actually a bug in this module, a bug in Windows, or maybe just some known limitation. As a test for my own application, I was passing random strings as arguments to verify they were escaped properly when passed as arguments. I found some strings which would have ^ dropped from it, but only if the command pipes STDERR to STDOUT. "quote_system_string" seems to be the correct subroutine to use for quoting arguments to be used with backticks, and backticks seems to be the only thread-safe way of capturing output on Windows. Strawberry Perl 5.24.1.1 Windows Server 2008 R2 Enterprise SP1 (64-bit) Strawberry Perl 5.30.0.1 Windows 10 Enterprise (1709, 64-bit) use strict; use Win32::ShellQuote 'quote_system_string'; if(@ARGV) { my $arg = pop(@ARGV); binmode(STDOUT); print $arg; exit(0); } my @args = ('^','^foo|^bar','foo"!^d bar','xeX]m"!^d 7MV"G{WV|X'); foreach my $arg(@args) { my @cmdarr = ($^X,$0,$arg); my $cmd = quote_system_string(@cmdarr); foreach my $acmd($cmd,"$cmd 2>&1") { print "\n$acmd\n$arg\n"; my $output = `$acmd`; if($output eq $arg) { print "$output: argument preserved\n"; } else { print "$output: argument mismatch\n"; } } }
On Tue Nov 05 14:18:39 2019, Chris.Denley@experian.com wrote: Show quoted text
> Not sure if this is actually a bug in this module, a bug in Windows, > or maybe just some known limitation. As a test for my own application, > I was passing random strings as arguments to verify they were escaped > properly when passed as arguments. I found some strings which would > have ^ dropped from it, but only if the command pipes STDERR to > STDOUT. "quote_system_string" seems to be the correct subroutine to > use for quoting arguments to be used with backticks, and backticks > seems to be the only thread-safe way of capturing output on Windows. > > Strawberry Perl 5.24.1.1 > Windows Server 2008 R2 Enterprise SP1 (64-bit) > > Strawberry Perl 5.30.0.1 > Windows 10 Enterprise (1709, 64-bit) > > use strict; > use Win32::ShellQuote 'quote_system_string'; > > if(@ARGV) { > my $arg = pop(@ARGV); > binmode(STDOUT); > print $arg; > exit(0); > } > > my @args = ('^','^foo|^bar','foo"!^d bar','xeX]m"!^d 7MV"G{WV|X'); > foreach my $arg(@args) { > my @cmdarr = ($^X,$0,$arg); > my $cmd = quote_system_string(@cmdarr); > foreach my $acmd($cmd,"$cmd 2>&1") { > print "\n$acmd\n$arg\n"; > my $output = `$acmd`; > if($output eq $arg) { > print "$output: argument preserved\n"; > } > else { > print "$output: argument mismatch\n"; > } > } > }
I don't have a Windows machine easily available to test on at the moment, but I'm fairly certain this is just a documentation issue. Backticks or system use heuristics to decide if the command used should be run directly or using cmd.exe. quote_system_string reimplements these heuristics, and quotes accordingly. But this only works if its output is passed directly to system or the backticks. '2>&1' is a shell construct, so adding it forces the command to be run using cmd.exe. quote_system_string doesn't know about this, so it can't make the correct decision on how to quote its output. The correct function to use in this case is quote_cmd, since you are forcing cmd.exe to be used. Backticks are not the only thread safe way to run other programs on Win32.
Date: Wed, 6 Nov 2019 16:35:59 +0000
Subject: RE: [rt.cpan.org #130905] ^ quote_system_string 2>&1
To: "bug-Win32-ShellQuote [...] rt.cpan.org" <bug-Win32-ShellQuote [...] rt.cpan.org>
From: "Denley, Chris" <Chris.Denley [...] experian.com>
I didn't even try quote_cmd as the documentation says it "quotes as a string" rather than "quotes as a list" like quote_system_string, and I need to pass it a list of arguments. But it does seem to take a list and work exactly as needed, resolving my issue. I assume passing "2>&1" in that list would result in that string being quoted and passed as an argument, which is why I was appending to the result. I initially wanted to use IPC::Run to capture the output from commands passed as a list, but it is not thread-safe on Windows. Otherwise it would've been perfect. Perhaps you're thinking of Win32::Process or something? Cross-platform would be ideal, but obviously in using Win32::ShellQuote we already have the quoting of arguments handled conditionally based on OS. I'm trying to keep that to a minimum though. Show quoted text
-----Original Message----- From: Graham Knop via RT <bug-Win32-ShellQuote@rt.cpan.org> Sent: Tuesday, November 5, 2019 4:41 PM To: Denley, Chris <Chris.Denley@experian.com> Subject: [rt.cpan.org #130905] ^ quote_system_string 2>&1 <URL: https://rt.cpan.org/Ticket/Display.html?id=130905 > On Tue Nov 05 14:18:39 2019, Chris.Denley@experian.com wrote:
> Not sure if this is actually a bug in this module, a bug in Windows, > or maybe just some known limitation. As a test for my own application, > I was passing random strings as arguments to verify they were escaped > properly when passed as arguments. I found some strings which would > have ^ dropped from it, but only if the command pipes STDERR to > STDOUT. "quote_system_string" seems to be the correct subroutine to > use for quoting arguments to be used with backticks, and backticks > seems to be the only thread-safe way of capturing output on Windows. > > Strawberry Perl 5.24.1.1 > Windows Server 2008 R2 Enterprise SP1 (64-bit) > > Strawberry Perl 5.30.0.1 > Windows 10 Enterprise (1709, 64-bit) > > use strict; > use Win32::ShellQuote 'quote_system_string'; > > if(@ARGV) { > my $arg = pop(@ARGV); > binmode(STDOUT); > print $arg; > exit(0); > } > > my @args = ('^','^foo|^bar','foo"!^d bar','xeX]m"!^d 7MV"G{WV|X'); > foreach my $arg(@args) { > my @cmdarr = ($^X,$0,$arg); > my $cmd = quote_system_string(@cmdarr); > foreach my $acmd($cmd,"$cmd 2>&1") { > print "\n$acmd\n$arg\n"; > my $output = `$acmd`; > if($output eq $arg) { > print "$output: argument preserved\n"; > } > else { > print "$output: argument mismatch\n"; > } > } > }
I don't have a Windows machine easily available to test on at the moment, but I'm fairly certain this is just a documentation issue. Backticks or system use heuristics to decide if the command used should be run directly or using cmd.exe. quote_system_string reimplements these heuristics, and quotes accordingly. But this only works if its output is passed directly to system or the backticks. '2>&1' is a shell construct, so adding it forces the command to be run using cmd.exe. quote_system_string doesn't know about this, so it can't make the correct decision on how to quote its output. The correct function to use in this case is quote_cmd, since you are forcing cmd.exe to be used. Backticks are not the only thread safe way to run other programs on Win32.
On Wed Nov 06 11:36:29 2019, Chris.Denley@experian.com wrote: Show quoted text
> I didn't even try quote_cmd as the documentation says it "quotes as a > string" rather than "quotes as a list" like quote_system_string, and I > need to pass it a list of arguments. But it does seem to take a list > and work exactly as needed, resolving my issue. I assume passing > "2>&1" in that list would result in that string being quoted and > passed as an argument, which is why I was appending to the result.
All of the functions take lists of arguments to be quoted, but some of them return lists as well. quote_system_string and quote_cmd both take lists and return a single string. If you have suggestions on how the documentation could be improved, they would be welcome. Show quoted text
> > I initially wanted to use IPC::Run to capture the output from commands > passed as a list, but it is not thread-safe on Windows. Otherwise it > would've been perfect. Perhaps you're thinking of Win32::Process or > something? Cross-platform would be ideal, but obviously in using > Win32::ShellQuote we already have the quoting of arguments handled > conditionally based on OS. I'm trying to keep that to a minimum > though. > > -----Original Message----- > From: Graham Knop via RT <bug-Win32-ShellQuote@rt.cpan.org> > Sent: Tuesday, November 5, 2019 4:41 PM > To: Denley, Chris <Chris.Denley@experian.com> > Subject: [rt.cpan.org #130905] ^ quote_system_string 2>&1 > > <URL: https://rt.cpan.org/Ticket/Display.html?id=130905 > > > On Tue Nov 05 14:18:39 2019, Chris.Denley@experian.com wrote:
> > Not sure if this is actually a bug in this module, a bug in Windows, > > or maybe just some known limitation. As a test for my own > > application, > > I was passing random strings as arguments to verify they were escaped > > properly when passed as arguments. I found some strings which would > > have ^ dropped from it, but only if the command pipes STDERR to > > STDOUT. "quote_system_string" seems to be the correct subroutine to > > use for quoting arguments to be used with backticks, and backticks > > seems to be the only thread-safe way of capturing output on Windows. > > > > Strawberry Perl 5.24.1.1 > > Windows Server 2008 R2 Enterprise SP1 (64-bit) > > > > Strawberry Perl 5.30.0.1 > > Windows 10 Enterprise (1709, 64-bit) > > > > use strict; > > use Win32::ShellQuote 'quote_system_string'; > > > > if(@ARGV) { > > my $arg = pop(@ARGV); > > binmode(STDOUT); > > print $arg; > > exit(0); > > } > > > > my @args = ('^','^foo|^bar','foo"!^d bar','xeX]m"!^d 7MV"G{WV|X'); > > foreach my $arg(@args) { > > my @cmdarr = ($^X,$0,$arg); > > my $cmd = quote_system_string(@cmdarr); > > foreach my $acmd($cmd,"$cmd 2>&1") { > > print "\n$acmd\n$arg\n"; > > my $output = `$acmd`; > > if($output eq $arg) { > > print "$output: argument preserved\n"; > > } > > else { > > print "$output: argument mismatch\n"; > > } > > } > > }
> > I don't have a Windows machine easily available to test on at the > moment, but I'm fairly certain this is just a documentation issue. > > Backticks or system use heuristics to decide if the command used > should be run directly or using cmd.exe. quote_system_string > reimplements these heuristics, and quotes accordingly. But this only > works if its output is passed directly to system or the backticks. > '2>&1' is a shell construct, so adding it forces the command to be run > using cmd.exe. quote_system_string doesn't know about this, so it > can't make the correct decision on how to quote its output. The > correct function to use in this case is quote_cmd, since you are > forcing cmd.exe to be used. > > Backticks are not the only thread safe way to run other programs on > Win32.
IPC::Open3 should be viable. my $pid = open3 *STDIN, my $fh, undef, quote_system_list('program', @args); my $output = do { local $/; <$fh> }; close $fh;