Compressed strings are often used to exchange Mathematica expressions on the Internet. It is, however, not easy to see what such expression will do after decompression. Resulting code can perform unwanted evaluations.
Here is a (somewhat stupid) example:
Warning: This will open a Youtube music video when decompressed!
str = "1:eJx9jt0KgkAQhbUfiC6CegOvA70Pogu1CARBX6BNZ1Fad8Wd9e/p200ouvHmY87MnMNxniKhtmVZcqMRtoQpgkAXZnPQ8EVVC8XzsK8bkLIUnFrmtte4c4SGE/ZIyuyVCMYm20rj1pT5FGtUVEr8V+laD8bi/DyJYiB3egiAEsUwZFABR7qc6fIxbzVSwAAYGSCf62d/3weJUMU18PSoZYFYy5PndV3nDkKheoKbicrrCGbFpT0H0dg349UfYjkTn5r4/g2cBFpg";
To see the uncompressed content without evaluation, I have tried to use Defer
(as suggested in this answer):
Uncompress[str, Defer]
but it does not prevent the video from being played.
How can I uncompress strings from internet safely, i.e. without any evaluation taking place?
Answer
This is definitely a bug. Here's a slightly simpler workaround than those suggested in the comments:
Uncompress[str, HoldComplete] // InputForm
Generally speaking, InputForm
and OutputForm
are safer than StandardForm
. This is for a couple of reasons. Much more of those textual formats happens inside the raw kernel, where evaluation leaks are easier to control. (I know of a couple, but really only because I can read the source code.) The second reason is that there is a class of evaluation which is allowed to happen during formatting, namely Dynamic
evaluation--this allows the FE to ask the kernel to evaluate pieces of the expression in order to display them or respond to user actions. Since the frontend will only do this for box-type (e.g, StandardForm
) cells, using InputForm
or OutputForm
will prevent these evaluations.
Edit and expansion in response to @Kuba's comment:
We do try hard to avoid evaluation leaks during formatting, but it can be quite challenging while also make things look "right" in the way most people want them to. And in, fact, this case (as well as Kuba's) shows one of the design issues that hasn't been quite solved.
DefaultElement
is an option to GridBox
. Options to boxes generally want expressions, not other boxes, as values. So we don't run MakeBoxes
on the input. But if the particular box is not HoldAll
, the expression isn't protected from further evaluation once MakeBoxes
is done. On the other hand, if the value isn't valid (whatever that means) there basically two possibilities: either disable formatting completely, or format with the value protected somehow (say replacing the Rule
by RuleDelayed
). But that will result in pink boxing in the FE. You'll notice that completely invalid inputs to typeset generators (say, Grid[{a}]
) don't format at all. In other cases, you get pinking (e.g., Hold[Graphics[{Red, Disk[]}]]
) (because GraphicsBox
is HoldAll
). Getting it completely right in all cases? Hard.
Comments
Post a Comment