Try running this code snippet in your browser:
eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS COOL') + "')); })()");
It will output THIS IS COOL
,
however, if you run the following:
eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()");
It will not work as expected, failing to print THIS IS "NOT" COOL
Could anyone shed light on why this occurs?
Pay attention to this detail:
The outcome of
JSON.stringify('THIS IS "NOT" COOL')
is the string "THIS IS \"NOT\" COOL"
If you attempt to parse
JSON.parse("THIS IS \"NOT\" COOL")
, it will fail since the JS parser will interpret the string "THIS IS \"NOT\" COOL"
as "THIS IS "NOT" COOL"
.
On the other hand, executing
JSON.parse(JSON.stringify('THIS IS "NOT" COOL'))
will work, as the string "THIS IS \"NOT\" COOL"
is passed directly to JSON.parse
.
Why does it succeed in one case, but not in the other?
I can only speculate that eval automatically unescapes any content passed to it before running the code, but I seek a definitive answer and understanding of why eval behaves in this manner.