[X2Go-Commits] [x2goserver] 26/30: x2goserver/lib/x2goupdateoptionsstring: handle options in a more robust way.
git-admin at x2go.org
git-admin at x2go.org
Thu Dec 13 11:22:51 CET 2018
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch master
in repository x2goserver.
commit 1759ca1e39f2c2a91abc9d37d5a40cef1bf902d2
Author: Mihai Moldovan <ionic at ionic.de>
Date: Thu Dec 13 08:52:15 2018 +0100
x2goserver/lib/x2goupdateoptionsstring: handle options in a more robust way.
First, we scan for unknown options and error out. If we find a
separating "--" pseudo-option, we keep that in mind and will not process
further options next time. Do this for every run of the transformation
loop.
---
debian/changelog | 5 +
x2goserver/lib/x2goupdateoptionsstring | 164 ++++++++++++++++++++++++++++++---
2 files changed, 157 insertions(+), 12 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 8ee6e8d..24a3137 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -63,6 +63,11 @@ x2goserver (4.1.0.4-0x2go1) UNRELEASED; urgency=medium
strings by replacing the switch statement with if statements.
"Fallthrough" doesn't mean the same thing as in C, apparently. Buyer
beware.
+ - x2goserver/lib/x2goupdateoptionsstring: handle options in a more robust
+ way. First, we scan for unknown options and error out. If we find a
+ separating "--" pseudo-option, we keep that in mind and will not process
+ further options next time. Do this for every run of the transformation
+ loop.
* debian/control:
+ Build-depend upon lsb-release for distro version detection.
* debian/x2goserver.manpages:
diff --git a/x2goserver/lib/x2goupdateoptionsstring b/x2goserver/lib/x2goupdateoptionsstring
index 1521d3e..6330d39 100755
--- a/x2goserver/lib/x2goupdateoptionsstring
+++ b/x2goserver/lib/x2goupdateoptionsstring
@@ -668,11 +668,107 @@ sub interpret_transform {
return $ret;
}
+# Helper function handling unknown options or ignoring the well-known
+# separator. It scans for options until hitting the first non-option entry.
+#
+# Takes an array reference with unparsed options and a boolean value denoting
+# whether the separating "--" pseudo-option should be skipped or not as its
+# parameters.
+#
+# Returns an array reference containing a boolean value denoting whether a
+# separating "--" pseudo-option has been found *and* skipping it was requested,
+# and the sanitized version of the original array reference.
+#
+# On error, returns undef.
+sub sanitize_program_options {
+ my $ret = undef;
+ my $error_detected = 0;
+ my $found_separator = 0;
+
+ my $args = shift;
+ my $skip_separator = shift;
+
+ if ((!(defined ($args))) || ('ARRAY' ne ref ($args))) {
+ print {*STDERR} "Invalid argument array reference passed to program sanitization helper, erroring out.\n";
+ $error_detected = 1;
+ }
+
+ if (!($error_detected)) {
+ if (!(defined ($skip_separator))) {
+ print {*STDERR} "No skip-separator parameter passed to program sanitization helper, erroring out.\n";
+ $error_detected = 1;
+ }
+ }
+
+ if (!($error_detected)) {
+ $args = dclone ($args);
+
+ my $opt = 1;
+ for (my $cur_arg = shift (@{$args}); ((defined ($cur_arg)) && ($opt)); $cur_arg = shift (@{$args})) {
+ if (q{-} eq substr ($cur_arg, 0, 1)) {
+ # Looks like an option so far. Let's continue scanning.
+
+ if (1 == length ($cur_arg)) {
+ # But isn't a real option. Add back to argument list and stop
+ # processing.
+ unshift (@{$args}, $cur_arg);
+ last;
+ }
+ elsif ((2 == length ($cur_arg)) && (q{-} eq substr ($cur_arg, 1, 1))) {
+ if ($skip_separator) {
+ # Found separating "--" pseudo-option, but skipping requested. Only
+ # set the boolean value for our return value.
+ $found_separator = 1;
+ }
+ else {
+ # Not skipping separating "--" pseudo-option - i.e., we'll treat this
+ # as a non-option.
+ unshift (@{$args}, $cur_arg);
+ last;
+ }
+ }
+ else {
+ # Otherwise this is an actual option.
+ # We either want to error out, if no previous separating "--"
+ # pseudo-option was found, or ignore it.
+ # The weird 0 + (...) construct here is forcing an arithmetic
+ # context. Otherwise, the interpreter might use a string context,
+ # in which the value "0" is dualvar'd to both an arithmetic 0 and
+ # an empty string.
+ my $separator_found = (0 + ((!($skip_separator)) | ($found_separator)));
+ if ($separator_found) {
+ # Put back into array. We'll handle this as not-an-option.
+ unshift (@{$args}, $cur_arg);
+ last;
+ }
+ else {
+ print {*STDERR} "Unknown option encountered: " . $cur_arg ."; erroring out.\n";
+ $error_detected = 1;
+ last;
+ }
+ }
+ }
+ else {
+ # Definitely not an option, add back to array.
+ unshift (@{$args}, $cur_arg);
+ last;
+ }
+ }
+ }
+
+ if (!($error_detected)) {
+ $ret = [ $found_separator, $args ];
+ }
+
+ return $ret;
+}
+
# Main function, no code outside of it shall be executed.
#
# Expects @ARGV to be passed in.
sub Main {
my $error_detected = 0;
+ my $found_separator = 0;
Getopt::Long::Configure ('gnu_getopt', 'no_auto_abbrev', 'pass_through');
@@ -689,13 +785,28 @@ sub Main {
pod2usage (-verbose => 2, -exitval => 3);
}
- my $options = shift;
+ my $sanitized_options = sanitize_program_options (\@_, (!($found_separator)));
- if (!(defined ($options))) {
- print {*STDERR} "No options string given, aborting.\n";
+ if (!(defined ($sanitized_options))) {
+ pod2usage (-exitval => 'NOEXIT');
$error_detected = 4;
}
+ my $options = undef;
+
+ if (!($error_detected)) {
+ $found_separator |= (0 + shift (@{$sanitized_options}));
+ $sanitized_options = shift (@{$sanitized_options});
+ @_ = @{$sanitized_options};
+
+ $options = shift;
+
+ if (!(defined ($options))) {
+ print {*STDERR} "No options string given, aborting.\n";
+ $error_detected = 5;
+ }
+ }
+
my $intermediate = undef;
if (!($error_detected)) {
@@ -707,11 +818,24 @@ sub Main {
if (!(defined ($intermediate))) {
print {*STDERR} "Unable to parse option string, aborting.\n";
- $error_detected = 5;
+ $error_detected = 6;
}
}
if (!($error_detected)) {
+ $sanitized_options = sanitize_program_options (\@_, (!($found_separator)));
+
+ if (!(defined ($sanitized_options))) {
+ pod2usage (-exitval => 'NOEXIT');
+ $error_detected = 7;
+ }
+ }
+
+ if (!($error_detected)) {
+ $found_separator |= (0 + shift (@{$sanitized_options}));
+ $sanitized_options = shift (@{$sanitized_options});
+ @_ = @{$sanitized_options};
+
my $cur_transform = shift;
if ($debug) {
@@ -719,13 +843,16 @@ sub Main {
}
# Nasty trick (to some degree): "do"-blocks are not recognized as loops by
- # Perl, but we can wrap the body in another block, which WILL BE recognized
- # as a loop (one, that only executes once), oddly enough.
- do {{
+ # Perl, but we could wrap the body in another block, which WILL BE recognized
+ # as a loop (one, that only executes once), oddly enough. However, using
+ # "last" won't work in such a situation, but rather behave like "next".
+ # Worse, the condition will also not be checked in such a case.
+ # Thus, we'd better use a real loop.
+ while (1) {
# Shall only be relevant for the first run of the loop.
if (!(defined ($cur_transform))) {
print {*STDERR} "No transformation passed, aborting.\n";
- $error_detected = 6;
+ $error_detected = 8;
last;
}
@@ -737,7 +864,7 @@ sub Main {
if (!(defined ($interpreted_transform_ref))) {
print {*STDERR} "Invalid transformation passed, aborting.\n";
- $error_detected = 7;
+ $error_detected = 9;
last;
}
@@ -751,14 +878,27 @@ sub Main {
if (!(defined ($intermediate))) {
print {*STDERR} "Error while transforming intermediate representation, aborting.\n";
- $error_detected = 7;
+ $error_detected = 10;
last;
}
if ($debug) {
print {*STDERR} 'Dumping transformed intermediate array: ' . Dumper ($intermediate);
}
- }} while (defined ($cur_transform = shift));
+
+ # Skip pseudo-option, if necessary.
+ $sanitized_options = sanitize_program_options (\@_, (!($found_separator)));
+
+ if (!(defined ($sanitized_options))) {
+ pod2usage (-exitval => 'NOEXIT');
+ $error_detected = 11;
+ last;
+ }
+
+ $found_separator |= (0 + shift (@{$sanitized_options}));
+ $sanitized_options = shift (@{$sanitized_options});
+ @_ = @{$sanitized_options};
+ } continue { last unless (defined ($cur_transform = shift)) };
}
my $out = undef;
@@ -768,7 +908,7 @@ sub Main {
if (!(defined ($out))) {
print {*STDERR} "Unable to transform intermediate back into string, aborting.\n";
- $error_detected = 8;
+ $error_detected = 12;
}
}
--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goserver.git
More information about the x2go-commits
mailing list