Jump to content

Having trouble with $CmdLine when parsing an arg with spaces and special chars


Recommended Posts

Hello all!  I'm trying to make a little script that sends a message over TCP.  An example payload would be:

MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>

Note how the payload contains special characters, and how the CDATA contains a SPACE (i.e.  "Not Running")

My compiled AU3 script expects exactly two command line arguments:

1) destination server/port expressed as 127.0.0.1:80

2) the payload I want to send to my server application (which may have multiple ATTRs, this example only has one ATTR)

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

 

My problems (plural) are with parsing of the second argument:

1)  If I don't wrap second argument in double-quotes, then Windows bails out before even launching EXE with "< was unexpected at this time"

2)  If I DO wrap second argument in double-quotes, then two problems can arise when my EXE parses the arguments:

             aa) The double-quotes are stripped from the CDATA value. ["Running"] is stored in the array as [Running]

             bb) If CDATA value DOES have a space, such as ["Not Running"], then I get an extra unwanted $CmdLine[3] because the SPACE between Not and Running is treated as a separator.  My second argument is thus split into two separate arguments, [2] and [3] instead of being treated as one arg stored in [2]

                        cc) Additionally, my script exits because it has an "IF $CmdLine[0] <>2 THEN Exit (1)" to validate the command line args.

I've tried launching the EXE with the second argument wrapped and escaped in a multitude of ways.  Double double-quotes, triple double-quotes, single-quotes on the outside with double-quotes inside (i.e.  '"ETC"'), starting the second arg with a caret (i.e. ^"ETC") and one of three things happens:

1) "< was unexpected at this time"

2) my CDATA value is stripped of its double-quotes

3) my payload argument gets split at the space in the CDATA value and the script bails out due to the unexpected 3rd argument.

 

Any ideas?  How can I preserve the second argument literally, including all special characters, quotes and spaces?

I tried adding some string manipulation code to grab the 2nd argument from $CmdLineRaw and it works (preserves the "Not Running" with quotes), but my number of arguments is still 3 instead of 2 if there is a space in the CDATA value.

 

Any assistance would be greatly appreciated!

Edited by jsmcpn
Link to comment
Share on other sites

Use $CmdLineRaw to get the whole parameter as a string and parse it yourself instead of letting the interpreter do it for you. Or use double quotes around the parameters that contain spaces.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

When I use the parameters like this they don't lose the double quotes around Not Running.

127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

 It shows in $CmdLineRaw like this.

127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

Here's the program I wrote to display it in the console window when it's run compiled.

#AutoIt3Wrapper_Change2CUI=y
#include <Array.au3>
_ArrayDisplay($cmdline)
ConsoleWrite($cmdlineraw & @CRLF)

Compile this, start the compiled program with the command line parameters as shown above and you'll see that it's not stripping the quotes inside the second parameter when displaying the $CmdLineRaw line. Parsing the string should be relatively easy from there.

Validating that it's run with 2 parameters would be a little harder, but I'm sure someone can come up with a RegEx answer to validate that criteria.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

  • 4 weeks later...

If the payload can contain absolutely any string of characters, then the problem remains somewhat complex. If, on the other hand, there exists some reasonably short string that will never appear in the payload, then you could use that string as a proxy for embedded double-quotes and wrap the entire argument in actual double-quotes. The argument count can then be checked, and your script would substitute a double-quote for each appearance of the proxy string.

E.g., if a run of three at-signs (@) can't appear in the payload, you could use that to replace the embedded double-quotes. In your example

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA["Not Running"]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

would become

MyApp.exe 127.0.0.1:80 "MY_PAYLOAD#<ATTRS><ATTR><NAME>MAILSERVER</NAME><OPERATION>set_value(ServiceStatus)</OPERATION><VALUE><![CDATA[@@@Not Running@@@]]></VALUE><TIMESTAMP>1349297031</TIMESTAMP></ATTR></ATTRS>"

and your script could use

StringReplace($CmdLine[2], "@@@", '"')

to do the substitution.

When the going gets tough, the tough start coding.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...