1

Contents of test.bat are:

setlocal EnableExtensions EnableDelayedExpansion
set param1=%~1
echo %param1%

Can someone explain why test.bat "^^!^^^&^^^^" makes the cmd window crash but test.bat "^^^&^^^^" has an expected result of setting &^ to variable param1?

I can do test.bat "pass^^!word" and I get the expected result of pass!word.

Update: test.bat "^^!^^^^^&^^^^^^^^" works. But I'm not completely sure why. This gets interpreted to set param1=^!^^&^^^^. Why does ^ need ^^^ in front of it?

Andriy M
  • 76,112
  • 17
  • 94
  • 154
Kevin Brotcke
  • 3,765
  • 26
  • 34
  • 1
    Probably because when you `EnableDelayedExpansion`, the `!` has a special meaning and you need to escape it. – adarshr Apr 02 '12 at 17:56

2 Answers2

2

You got many problems, as the special characters will be evaluated mulitple times in your case.

First in the set command, the special character phase will reduce your string "^^!^^^&^^^^" to
^!^&^^
But as delayed expansion is enabled and your string contains an exclamation mark,
another phase will be enabled to reduce the carets again to.
!&^

At this point param1 contains !&^, you can test it with set param1

But as you try to echo the value with echo %param1% another expansion will be executed.
And now you get a problem, as %param1% will expand to !&^,
The exclamation mark will be removed, as the second exlamation mark is missing for expanding a variable,
the ampersand will be treated as new command separator and
the ending caret will be treated as multiline character.
echo ! & ^<next line>

It's much safer to use the delayed expansion here, as this never change the content, as this phase is the last one of the parser.

setlocal EnableDelayedExpansion
set param1=%~1
set param1
echo !param1!

And all these explanations can be found at How does CMD.EXE parse scripts?

Community
  • 1
  • 1
jeb
  • 78,592
  • 17
  • 171
  • 225
1

It is because the escape character for the Windows shell is ^, so:

"^^!^^^^^&^^^^^^^^"

Each ^^ becomes ^

Each ^& becomes &

So finally you will get:

"^!^^&^^^^"

Joe DF
  • 5,438
  • 6
  • 41
  • 63
  • No he will not get `"^!^^&^^^^"`, the quotes are removed by the tilde in `%~1` and the more carets will be removed by the exlamation mark. – jeb Apr 03 '12 at 08:21
  • but only if he uses "EnableDelayedExpansion",... I think..?? yes/no? – Joe DF Apr 03 '12 at 21:36
  • Yes, only if EnabledDelayedExpansion AND at least one exclamation mark is anywhere on the line, but then the carets are evaluated outside and inside of quotes. `echo "^^^^" ^^^^ x!` results to `"^^" ^ x` – jeb Apr 04 '12 at 16:39