Skip to main content

bugs - How to uncompress strings safely (without any evaluation)?


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

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....