Bug#1028963: Surprise restriction of the qx_cmd() function in Dh_Lib.pm

2023-01-15 Thread Niels Thykier

Control: tags -1 wontfix
Control: retitle -1 Dh_Lib: qx_cmd does not support shell features

Gunnar Hjalmarsson:

Package: debhelper
Version: 13.11.1

Hello!

The fix of https://bugs.debian.org/1016354 resulted in a regression so 
Ubuntu's debhelper extension dh-translations stopped working.


This is the commit:

https://salsa.debian.org/debian/debhelper/-/commit/62a8608e

The qx_cmd() function has been used conveniently in dh_translations to 
grab the output from a few commands which make use of pipes. Now that 
doesn't work any longer. It was resolved for now by copying the qx_cmd() 
function as it looked like before commit 62a8608e into dh_translations. 
Please see the attached diff.


This raises the question if there is a need also for a 'cleaner' qx_cmd 
function. Maybe "complex_qx_cmd" (compare complex_doit).




The `qx_cmd` is specifically there for avoiding a shell.  It is 
unfortunate that it had an unintentional special case where 
`dh_translations` could "abuse" it and get a shell behaviour.


If you want a shell, you can just use perl's qx operator (`perldoc -f 
qx`), which is a "built-in", well documented and does not require any 
backwards compat tricks from dh-translations or debhelper.


Thanks,
~Niels



Bug#1028963: Surprise restriction of the qx_cmd() function in Dh_Lib.pm

2023-01-15 Thread Gunnar Hjalmarsson

Package: debhelper
Version: 13.11.1

Hello!

The fix of https://bugs.debian.org/1016354 resulted in a regression so 
Ubuntu's debhelper extension dh-translations stopped working.


This is the commit:

https://salsa.debian.org/debian/debhelper/-/commit/62a8608e

The qx_cmd() function has been used conveniently in dh_translations to 
grab the output from a few commands which make use of pipes. Now that 
doesn't work any longer. It was resolved for now by copying the qx_cmd() 
function as it looked like before commit 62a8608e into dh_translations. 
Please see the attached diff.


This raises the question if there is a need also for a 'cleaner' qx_cmd 
function. Maybe "complex_qx_cmd" (compare complex_doit).


--
Cheers,

Gunnar Hjalmarsson--- /usr/bin/dh_translations.orig	2019-02-05 16:05:37.0 +0100
+++ /usr/bin/dh_translations	2023-01-14 09:15:08.190676370 +0100
@@ -55,6 +55,26 @@
 
 my ($domain, $use_intltool, $meson_builddir);
 
+# This is the version of the qx_cmd() function in Dh_Lib.pm before
+# https://salsa.debian.org/debian/debhelper/-/commit/62a8608
+sub qx_meson_cmd {
+	my (@cmd) = @_;
+	my ($output, @output);
+	open(my $fd, '-|', @cmd) or error('fork+exec (' . escape_shell(@cmd) . "): $!");
+	if (wantarray) {
+		@output = <$fd>;
+	} else {
+		local $/ = undef;
+		$output = <$fd>;
+	}
+	if (not close($fd)) {
+		error("close pipe failed: $!") if $!;
+		error_exitcode(escape_shell(@cmd));
+	}
+	return @output if wantarray;
+	return $output;
+}
+
 # figure out intltool usage and domain
 sub check_buildsystem {
 $use_intltool = 0;
@@ -88,7 +108,7 @@
 
 $meson_builddir = File::Spec->rel2abs($dirs[0]);
 
-my $all_domains = qx_cmd ("meson introspect '$meson_builddir' --targets | jq -r -M '.[].name | select(endswith(\"-pot\")) | sub(\"-pot\"; \"\")'");
+my $all_domains = qx_meson_cmd ("meson introspect '$meson_builddir' --targets | jq -r -M '.[].name | select(endswith(\"-pot\")) | sub(\"-pot\"; \"\")'");
 
 my @domains = split (' ', $all_domains);
 
@@ -101,10 +121,10 @@
 } else {
 # meson 0.49 changed the property name from 'name' to 'descriptive_name'
 # prevent confusion due to possible help-* domain
-my $project = qx_cmd ("meson introspect '$meson_builddir' --projectinfo | jq -r '.descriptive_name'");
+my $project = qx_meson_cmd ("meson introspect '$meson_builddir' --projectinfo | jq -r '.descriptive_name'");
 chomp $project;
 if ($project eq "null") {
-$project = qx_cmd ("meson introspect '$meson_builddir' --projectinfo | jq -r '.name'");
+$project = qx_meson_cmd ("meson introspect '$meson_builddir' --projectinfo | jq -r '.name'");
 chomp $project;
 }
 @domains = grep { $_ ne 'help-'.$project } @domains;