Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

appclient can't pass arguments with double-quote properly. #21863

Closed
glassfishrobot opened this issue Jun 16, 2017 · 3 comments · Fixed by #23655
Closed

appclient can't pass arguments with double-quote properly. #21863

glassfishrobot opened this issue Jun 16, 2017 · 3 comments · Fixed by #23655

Comments

@glassfishrobot
Copy link

appclient can't pass arguments with double-quote properly.
There are multiple problems for only Windows, for only Linux, and for both Windows and Linux.

Environment Details

  • GlassFish Version: 4.1.2, 5.0-b08
  • JDK version: 1.8.0_65
  • OS: Windows 7, Red Hat Enterprise Linux 6.5

Problem Description

appclient can't pass arguments with double-quote properly.

Using this sample appclient program to check passed arguments.
Sample appclient program is attached as EchoAppclient.zip

public class Main {
    public static void main(String[] args) {
        for(int i=0; i < args.length; i++){
            System.out.println("args["+(i)+"]="+"["+args[i]+"]");
        }
    }
}

Whitespace is trimmed when argument length <= 2 (Windows, Linux)

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a " " b" " "
args[0]=[a ]
args[1]=[ b]
args[2]=[ ]

but was (args[2] is not passed)

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a " " b" " "
args[0]=[a]
args[1]=[b]

Multiple whitespaces become single whitespace (Linux)

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a  b"
args[0]=[a  b]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a  b"
args[0]=[a b]

Escape-sequence don't work in double-quote (Windows)

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b"
args[0]=[a"b]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b"
args[0]=[a\]
args[1]=[b]

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a \" b \" c"
args[0]=[a " b " c]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a \" b \" c"
args[0]=[a "  b  \   c]

Escape-sequence is evaluated twice (Linux)

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b"
args[0]=[a"b]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b"
./appclient: eval: line 102: unexpected EOF while looking for matching `"'
./appclient: eval: line 103: syntax error: unexpected end of file
./appclient: line 103: warning: syntax errors in . or eval will cause future versions of the shell to abort as Posix requires

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b\"c"
args[0]=[a"b"c]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a\"b\"c"
args[0]=[abc]

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a \" b \" c"
args[0]=[a " b " c]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "a \" b \" c"
args[0]=[a ]
args[1]=[b]
args[2]=[ c]

Expected is

> appclient -client /path/to/appclient/EchoAppclientClient.jar "\\\""
args[0]=[\"]

but was

> appclient -client /path/to/appclient/EchoAppclientClient.jar "\\\""
args[0]=["]

Steps to reproduce

  1. asadmin start-domain
  2. asadmin deploy EchoAppclient.jar (attached)
  3. asadmin get-client-stubs --appname EchoAppclient /path/to/client
  4. appclient -client /path/to/client/EchoAppclientClient.jar "a " " b" " " "a b" "a\"b\"c" "a \" b \" c" "\\\""

Fix

appclient calls CLIBootstrap class to generate java command line string, then appclient calls that command line string to execute appclient main program.
In Windows, environment variable is used to pass arguments to CLIBootstrap. So parsing environment variables is required in CLIBootstrap.
In Linux, eval command is used to execute java command line string generated by CLIBootstrap.

Whitespace is trimmed when argument length <= 2 (Windows, Linux)

CLIBootstrap.quote(String) method quotes argument with double-quote if argument length > 2. As argument with length <=2 is not quoted, whitespace is trimmed when executing command line string generated by CLIBootstrap.

CLIBootstrap.quote(String) is used other than quoting arguments, so create new inner class CommandLineArgument (which extends CommandLineElement) to fix quoting command line arguments only.

diff --git "a/C:\\Users\\uno\\AppData\\Local\\Temp\\CLI7AD2.tmp\\CLIBootstrap-HEAD-left.java" "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\acc\\src\\main\\java\\org\\glassfish\\appclient\\client\\CLIBootstrap.java"
index 8ac3e92..96d7433 100644
--- "a/C:\\Users\\uno\\AppData\\Local\\Temp\\CLI7AD2.tmp\\CLIBootstrap-HEAD-left.java"
+++ "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\acc\\src\\main\\java\\org\\glassfish\\appclient\\client\\CLIBootstrap.java"
@@ -279,7 +279,7 @@ public class CLIBootstrap {
 
         otherJVMOptions = new JVMOption("-.*", userVMArgs.evOtherJVMOptions);
 
-        arguments = new CommandLineElement(".*", Pattern.DOTALL);
+        arguments = new CommandLineArgument(".*", Pattern.DOTALL);
 
         initCommandLineElements();
     }
@@ -548,6 +548,30 @@ public class CLIBootstrap {
         }
     }
 
+    private class CommandLineArgument extends CommandLineElement {
+
+        CommandLineArgument(String patternString, int flags) {
+            super(patternString, flags);
+        }
+
+        @Override
+        StringBuilder format(final StringBuilder commandLine, 
+                final boolean useQuotes, final String v) {
+            if (commandLine.length() > 0) {
+                commandLine.append(' ');
+            }
+            commandLine.append((useQuotes ? quoteCommandLineArgument(v) : v));
+            return commandLine;
+        }
+
+        private String quoteCommandLineArgument(String s) {
+            if(! OS.isWindows()) {
+                s = s.replace("\\", "\\\\").replace("\"", "\\\"").replace("$", "\\$").replace("`", "\\`");
+            }
+            return "\"" + s + "\"";
+        }
+    }
+
     /**
      * A command-line option (an element which starts with "-").
      */

Multiple whitespaces become single whitespace (Linux)

Escape-sequence is evaluated twice (Linux)

These two problems have same cause: command line arguments are evaluated twice.

  1. Command line arguments are evaluated when calling CLIBootstrap.
  2. Eval command re-evaluates command line arguments generated by CLIBootstrap.

To avoid evaluating command line arguments twice, double-quoted single argument must be passed to eval command.
So adding double-quote to whole eval command arguments fixes these problems.

diff --git "a/C:\\Users\\uno\\AppData\\Local\\Temp\\app3210.tmp\\appclient-HEAD-left" "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\appclient-scripts\\src\\main\\resources\\glassfish\\bin\\appclient"
index d70be0a..944456b 100644
--- "a/C:\\Users\\uno\\AppData\\Local\\Temp\\app3210.tmp\\appclient-HEAD-left"
+++ "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\appclient-scripts\\src\\main\\resources\\glassfish\\bin\\appclient"
@@ -99,4 +99,4 @@ esac
 
 chooseJava
 
-eval `"${ACCJava}" -Dorg.glassfish.appclient.shell $cygwinProp -classpath "${_AS_INSTALL}/lib/gf-client.jar" org.glassfish.appclient.client.CLIBootstrap "$@"`
\ No newline at end of file
+eval "`"${ACCJava}" -Dorg.glassfish.appclient.shell $cygwinProp -classpath "${_AS_INSTALL}/lib/gf-client.jar" org.glassfish.appclient.client.CLIBootstrap "$@"`"
\ No newline at end of file

Escape-sequence don't work in double-quote (Windows)

CLIBootstrap parses environment variables using RegExp. But this RegExp pattern doesn't consider escape-sequence in double-quote. So fix RegExp pattern to consider escape-sequence in double-quote.

  • Double-quote following odd number of backslash doesn't split arguments. (double-quote is escaped)
  • Double-quote following even number of backslash split arguments. (double-quote is not escaped)
diff --git "a/C:\\Users\\uno\\AppData\\Local\\Temp\\CLI3683.tmp\\CLIBootstrap-HEAD-left.java" "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\acc\\src\\main\\java\\org\\glassfish\\appclient\\client\\CLIBootstrap.java"
index 8ac3e92..8b10fe0 100644
--- "a/C:\\Users\\uno\\AppData\\Local\\Temp\\CLI3683.tmp\\CLIBootstrap-HEAD-left.java"
+++ "b/D:\\repo\\external\\glassfish\\appserver\\appclient\\client\\acc\\src\\main\\java\\org\\glassfish\\appclient\\client\\CLIBootstrap.java"
@@ -217,7 +217,7 @@ public class CLIBootstrap {
          * containing no double quote) or a non-quoted string (a string containing
          * no white space or quotes).
          */
-        final Pattern argPattern = Pattern.compile("\"([^\"]+)\"|([^\"\\s]+)");
+        final Pattern argPattern = Pattern.compile("\"((?:(?<!\\\\)(?:(?:\\\\\\\\)*\\\\)\"|[^\"])*)\"|([^\"\\s]+)");
 
         final Matcher matcher = argPattern.matcher(inputArgs);
         final List<String> argList = new ArrayList<String>();
@glassfishrobot
Copy link
Author

@amykang2020 Commented
These are nice to have fixes for appclient, not a must for GlassFish 5.0

@glassfishrobot
Copy link
Author

st24 added a commit to st24/glassfish that referenced this issue Nov 19, 2019
…n client arguments (eclipse-ee4j#21863)

Signed-off-by: st24 <sato-tsuyoshi@fujitsu.com>
@github-actions
Copy link

This issue has been marked as inactive and old and will be closed in 7 days if there is no further activity. If you want the issue to remain open please add a comment

@github-actions github-actions bot added the Stale label Mar 11, 2020
arjantijms added a commit that referenced this issue Oct 20, 2021
Fix #21863 appclient can't pass arguments with double-quote properly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant