1

Passing an argument that contains an exclamation mark (!) to a groovy script from a Windows command line gets stripped away because Windows is trying to expand a variable name using delayed expansion (see this, this, and this). There are quite a few solutions posted that incorporate one of these solutions:

  • setlocal ENABLEDELAYEDEXPANSION
  • Escaping "with quotes^!"
  • Escaping without quotes^^!

These are all accepted answers so apparently it works in some cases but it's NOT working for me. Here's the behavior I get on Windows 10 Professional:

C:\sof>type cmdtest.groovy
PASSWD=args[0]
println PASSWD

C:\sof>groovy cmdtest.groovy foopasswd!
foopasswd

C:\sof>groovy cmdtest.groovy foopasswd^^!
foopasswd

C:\sof>groovy cmdtest.groovy "foopasswd^!"
foopasswd

C:\sof>setlocal DisableDelayedExpansion

C:\sof>groovy cmdtest.groovy foopasswd!
foopasswd

C:\sof>groovy cmdtest.groovy foopasswd^^!
foopasswd

I figure it's somehow happening in the groovy.bat so I also tried adding setlocal DisableDelayedExpansion to groovy.bat and it also didn't work.

Can somehow tell me the trick to make the above cmdtest.groovy respect the !'s?

AndyJ
  • 1,204
  • 3
  • 14
  • 28

1 Answers1

1

The problem are the files groovy.bat and startgroovy.bat, they contain poor batch code.
startgroovy.bat enables delayed expansion, but doesn't use it!

The parameters are transfered from groovy.bat to startgroovy.bat by using %* in the line.

"%DIRNAME%\startGroovy.bat" "%DIRNAME%" groovy.ui.GroovyMain %*

There the first carets will be removed, but how many is undetermined, because it's not reliable if delayed expansion is enabled or not. In startgroovy.bat delayed expansion is enabled and the arguments are stored by lines like set CP=%~2.
There the next carets will be removed.
But when the arguments reaches the block:

rem escape minus (-d), quotes (-q), star (-s).
set _ARGS=%*
if not defined _ARGS goto execute
set _ARGS=%_ARGS:-=-d%
set _ARGS=%_ARGS:"=-q%
...

All hope is lost, here it's impossible to preserve an exclamation mark

If you want to repair this, you need to replace all %ARGS:...% expressions with -!ARGS:...!.

set _ARGS=!_ARGS:-=-d!
set _ARGS=!_ARGS:"=-q!

But the function :win9xME_args_loop is also broken.

:win9xME_args_loop
rem split args by spaces into first and rest
for /f "tokens=1,*" %%i in (!_ARGS!) do call :get_arg "%%i" "%%j"
goto process_arg

The call ... "%%i" "%%j" will not work with carets/exclamation marks, this have to be refactored to something like:

for /f "tokens=1,*" %%i in ("!_ARGS!") do (
   set "_ARG=!_ARG! %%~i"

But my conclusion is: Don't try to use special characters in your password.
A complete rewrite of the groovy batch files is necessary, currently the files are a good example of anti-pattern

jeb
  • 78,592
  • 17
  • 171
  • 225
  • lol! Thank you for that enjoyable and informative write-up! I will keep a reference to this as instruction if it ever becomes so crucial but for now will take your advice and just be mindful of special characters. This is an edge case in our scenario but it was driving me batty and I wanted to understand the issue. Appreciate your help. – AndyJ Apr 25 '19 at 22:54