call
Caret Escaping Bug in IBM's cmd
and Microsoft's cmd
.What's the gen on the CALL caret escaping bug in Microsoft's CMD and IBM's CMD ?
This is the Frequently Given Answer to that question.
The call
Caret Escaping Bug is a bug in the
call
commands that are built into Microsoft's
cmd
and IBM's cmd
. They do not perform the
correct inverse of the transformation that the command interpreters'
parsers perform when handling the escaping of metacharacters in a
command line.
The way that the parsers in Microsoft's cmd
and IBM's
cmd
treat carets (and, indeed, other metacharacters) within
quoted portions of the command line is not documented, of course.
However, it is discernable through experimentation.
The way that the call
command is supposed to handle
metacharacters on its command tail is also not documented. However, it
is readily apparent, from the fact that Microsoft's and IBM's
cmd
even attempt to perform a transformation, that
the intention is that call
does not cause escape character
processing to be performed twice.
The bug is present in all versions of Microsoft's cmd
for
Windows NT, and in IBM's cmd
for OS/2.
This bug is not present in any version of command
. No
version of command
, be it Microsoft's command
,
IBM's command
, Digital Research's command
, or
FreeCOM, supports the escaping of metacharacters.
This bug is not present in JP Software's various command interpreters.
4DOS, 4OS2, 4NT, TCWIN16, TCWIN32, and TCOS2 all support the escaping of
metacharacters, albeit operating differently to the way that Microsoft's
and IBM's cmd
s operate, but all of their built-in
call
commands perform the inverse transformation correctly.
This bug is not present in the 32-bit
cmd
for OS/2. The 32-bit cmd
also handles
the escaping of metacharacters differently to the way that Microsoft's
and IBM's cmd
s handle it. But, likewise, its built-in
call
command performs the appropriate inverse transformation
correctly.
The severity of this bug is not easily quantifiable.
This bug causes a command to be passed a command tail different to the one that the user actually specified in the original command line. The severity of this depends from what command is actually being invoked, and what the effect of extra caret characters in the command tail of that command will be.
Execute the command
CALL ECHO ^^A "^^A"
(The echo
command used here is chosen merely for the sake of
example, and is not germane to the nature of the bug.)
The correct output that Microsoft's cmd
and IBM's
cmd
should generate, given their (undocumented) rules about
the handling of carets in quoted portions of the command line, is
^A "^^A"
however the output that they actually generate is
^A "^^^^A"
with twice as many caret characters in the quoted portion as there should be.
There are no access controls or privileges that relate directly to this bug.
A program that attempted to sanitise an argument string supplied from an
external source, by escaping any embedded metacharacters, for passing to
a command via the command interpreter, would cause unexpected results if
the string contained caret characters and the program was invoking the
call
command. However, this scenario is unlikely to occur
in practice.
When one issues the command
CALL ECHO ^^A "^^A"
the call
command of course "sees" the command tail
after escape character processing has been performed on it by
the command interpreter, so it sees
ECHO ^A "^^A"
as its command tail. However, the call
command effectively
resubmits the command tail that it receives back to the command
interpreter as a new command line to be executed. So it must escape any
carets in its input in order to prevent their being processed as
metacharacters, since metacharacter processing has already been done
once. call
, therefore, prepends escape characters in front
of any carets before resubmitting its command tail for execution.
Unfortunately, what call
is doing, to ensure that what
results once the parser has had a second go at processing the command
line is the same as what call
originally received, doesn't
exactly match the processing that the command line parser actually does.
call
is not performing the exact inverse of the
transformation that the command interpreter performs. The parsers of
Microsoft's and IBM's cmd
s only recognise caret as a
metacharacter outside of those parts of the command line that
are contained between pairs of quotation marks. But call
is escaping carets everywhere that they occur, irrespective of
quotation marks.
The result of this is that if a caret is surrounded by a pair of
quotation marks in the command tail to call
, two carets
will occur at that point in the command tail of the command that is
eventually executed. In other words: call
constructs the
string
ECHO ^^A "^^^^A"
to pass back to the command interpreter, by escaping all carets in the
command tail that it received; which becomes
ECHO ^A "^^^^A"
after metacharacter processing by the command interpreter; resulting in the
ECHO command seeing, and echoing, the command tail
^A "^^^^A"
.
In order to correctly perform the inverse of the transformation
performed by the command interpreter, the call
command
should actually have constructed the string
ECHO ^^A "^^A"
to pass back to the command interpreter, by escaping only those carets
that are not quoted by pairs of quotation marks.
There is no known local fix for this bug. Given the analysis, it does not appear likely that a local fix is possible.
As yet, IBM has not released a temporary fix for this bug, and Microsoft has issued no hotfix for this bug.
As yet, IBM has issued no fix pack and Microsoft has issued no service pack that includes a fix for this bug.
(There will not be further service packs for Windows NT 4. This is a permanent bug in Windows NT 4.)