I need to pass different strings formatted as json to a json parser.
Problem is that jQuery.parseJSON() and JSON.parse() only support a very strict json format:
Passing in a malformed JSON string may result in an exception being thrown. For example, the following are all malformed JSON strings:
{test: 1} (test does not have double quotes around it).
{'test': 1} ('test' is using single quotes instead of double quotes).
Is there a less restrictive parser that will allow passing values like that (without quotes or with single quote)?
BTW, I'm using KO 2.2.1 so if it has something like that it would be helpful.
There is a node module called jsonic that parses non strict JSON.
npm install jsonic
You might also use eval:
var parsed = eval(json)
Be careful because eval could also run code so you must be sure that you know what you are parsing.
There is no such thing as a less strict JSON parser. You're either dealing with well-formed JSON, or you're not dealing with JSON at all. To parse your custom format, you may want to take a look at Crockford's parser source code, and modify it to fit your needs.
Or, for a quick and dirty solution you might just use eval (but be aware its use has security implications).
Related
My motive is to mangle variable and function names and also encrypt strings in a javascript file.
For this I only need to separate strings, comments, and variable/function names.
I've tried UglifyJs2 but I need more control on myself so I tried to write a lexer myself using Flex.
I'm able to take care of comments and quoted strings.
However I'm stuck in regular expression format for example /"/ -- a regular expression containing quotes causing correct parsing to fail.
Looks like to correctly identify a regular expression i'd need Bison parser using grammar rules otherwise comments, strings and regular expression get mixed up.
I don't want to get that far and use Bison.
One way is to move all regular expression code to another file in functions.
Is there any other alternative so that I can handle this in Flex itself?
If you can run JavaScript, you can use Esprima, a JavaScript parser coded in JavaScript. It can even run in your browser or any runtime like NodeJS.
It can output just tokens or abstract syntax trees. I believe that this should enough for you.
As part of a MongoDB script, I need to parse JSON. (Not something you would typically do, but it is Javascript after all).
JSON.parse does not exist.
Here is the workaround I made:
function parseJSON(json) {
return eval("(function() { return "+json+"; })()");
}
This doesn't seem like it would be performant, and it looks a little ridiculous. Does anyone have a better way?
If you really have to convert a JSON string into a JavaScript object, then what you suggest is perfectly reasonable, although there are reasons to avoid eval due to performance concerns and security risks (see When is JavaScript's eval() not evil?). In the case that you generated the JSON data and you are sure that there's nothing dangerous inside, then you probably don't have to worry about an injection vulnerability.
As far as performance, I'm not aware of anything better other than JSON.parse. Can you alter the design of your program so that you do not have to parse JSON? For example, for importing JSON data into MongoDB, instead of using eval you should use the mongoimport utility.
I've been having some troubles with parsing JSON that is received with WebSocket (original question - Parse JSON received with WebSocket results in error). The JSON string itself is valid (tested with several JSON validators), but JSON.parse throws an exception. I am trying to figure out what is it exactly that it cannot parse, but the only thing I'm getting is "SyntaxError: unexpected_token ILLEGAL", it doesn't say where is the exact position of the failed token. Is there any way of extracting such information?
Update: If I copy-paste that JSON string to a static file (e.g. "data.json") and then retrieve it and parse it with the same function (JSON.parse) - then it works fine.
So I'm assuming there's something tricky going on, I thought of newline symbol (may be there was \n instead of \r\n or vice versa) but completely removing all the line breaks didn't help. I would think that it very well may be an encoding problem, but the data is received via websocket and according to documentation it's utf-8 string.
2nd Update: IT WORKS just fine if I use "json_parse" from here: https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
Then it works fine! Does that mean this is a bug in "JSON.parse" implementation used by Chrome or what?
Thank you.
You could copy an implementation of JSON.parse() from somewhere (like out of jQuery), change it's name so you can call it directly, tweak the implementation so that it never detects the built-in parser so it always uses the JS parser and then change your code to use the new JS version of the parser, then trace through it in a javascript debugger until you find what it doesn't like.
One thing to check is if you have quotes and slashes within your JSON string. If yes, they need to be escaped:
{
"key": "i've \"quotes\" in me",
"key2": "and \\slashes too"
}
Also, JSONLint gives you the exact location of the error.
As per JSON.org, you cannot have quotes and slashes in your strings, so you need to escape them.
I think you don't need to call JSON.parse:
JSON.parse({"key": "whatever"}) // Syntax Error ILLEGAL
because it's already an object. I would also be curious to see the result of the following code:
eval("(" + json + ")");
Or
JSON.parse(decodeURIComponent(json));
Can't tell much with the details, but the possibility may be that your validator is doing non-strict parsing and your javascript may be doing strict parsing...
My Spider Sense warns me that using eval() to parse incoming JSON is a bad idea. I'm just wondering if JSON.parse() - which I assume is a part of JavaScript and not a browser-specific function - is more secure.
You are more vulnerable to attacks if using eval: JSON is a subset of Javascript and json.parse just parses JSON whereas eval would leave the door open to all JS expressions.
All JSON.parse implementations most likely use eval()
JSON.parse is based on Douglas Crockford's solution, which uses eval() right there on line 497.
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
The advantage of JSON.parse is that it verifies the argument is correct JSON syntax.
Not all browsers have native JSON support so there will be times where you need to use eval() to the JSON string. Use JSON parser from http://json.org as that handles everything a lot easier for you.
Eval() is an evil but against some browsers its a necessary evil but where you can avoid it, do so!!!!!
There is a difference between what JSON.parse() and eval() will accept. Try eval on this:
var x = "{\"shoppingCartName\":\"shopping_cart:2000\"}"
eval(x) //won't work
JSON.parse(x) //does work
See this example.
If you parse the JSON with eval, you're allowing the string being parsed to contain absolutely anything, so instead of just being a set of data, you could find yourself executing function calls, or whatever.
Also, JSON's parse accepts an aditional parameter, reviver, that lets you specify how to deal with certain values, such as datetimes (more info and example in the inline documentation here)
JSON is just a subset of JavaScript. But eval evaluates the full JavaScript language and not just the subset that’s JSON.
Quick Question. Eval in JavaScript is unsafe is it not? I have a JSON object as a string and I need to turn it into an actual object so I can obtain the data:
function PopulateSeriesFields(result)
{
data = eval('(' + result + ')');
var myFakeExample = data.exampleType
}
If it helps I am using the $.ajax method from jQuery.
Thanks
Well, safe or not, when you are using jQuery, you're better to use the $.getJSON() method, not $.ajax():
$.getJSON(url, function(data){
alert(data.exampleType);
});
eval() is usually considered safe for JSON parsing when you are only communicating with your own server and especially when you use a good JSON library on server side that guarantees that generated JSON will not contain anything nasty.
Even Douglas Crockford, the author of JSON, said that you shouldn't use eval() anywhere in your code, except for parsing JSON. See the corresponding section in his book JavaScript: The Good Parts
You should use JSON and write JSON.parse.
"Manual" parsing is too slow, so JSON.parse implementation from the library checks stuff and then ends up using eval, so it is still unsafe. But, if you are using a newer browser (IE8 or Firefox), the library code is not actually executed. Instead, native browser support kicks in, and then you are safe.
Read more here and here.
If you can't trust the source, then you're correct...eval is unsafe. It could be used to inject code into your pages.
Check out this link for a safer alternative:
JSON in Javascript
The page explains why eval is unsafe and provides a link to a JSON parser at the bottom of the page.
Unsafe? That depends on if you can trust the data.
If you can trust that the string will be JSON (and won't include, for example, functions) then it is safe.
That said - if you are using jQuery, why are you doing this manually? Use the dataType option to specify that it is JSON and let the library take care of it for you.
If you are using jQuery, as of version 1.4.1 you can use jQuery.parseJSON()
See this answer: Safe json parsing with jquery?
Using JavaScript’s eval is unsafe. Because JSON is just a subset of JavaScript but JavaScript’s eval allows any valid JavaScript.
Use a real JSON parser like the JSON parser from json.org instead.
The alternative to evaluating the code is to parse it manually. It's not as hard as it sounds but it's quite a lot heavier at runtime. You can read about it here.
The important part to note is evaluating JSON is not inherently insecure. As long as you trust the source not to balls things up. That includes making sure that things passed into the JSON encoder are properly escaped (to stop people 2 steps up the stream executing code on your users' machines).
you can try it like this
var object = new Function("return " + jsonString)()
Another great alternative is YUI:
http://yuilibrary.com/yui/docs/json/
So your code would be something like:
Y.JSON.parse('{"id": 15, "name": "something"}');