JSON Parsing error with backslash - javascript

I have been trying to figure out why the following JSON input will be failed to parse in JSON.parse function.
{"World":"Hello\\Test"}
The json above is being returned by JSON.NET.
I have tried multiple methods to get this working. As you can see the backslash is escaped and https://jsonlint.com/ is able to parse it.
I have a failing sample at https://jsfiddle.net/ckp0uc0p/3/ as well.
Any help will be appreciated.

The best way to inject JSON into JavaScript source code (when generating the JavaScript with a server side language), is to inject it directly where you need it, not inside a string literal that needs to be parsed.
For example:
var foo = <json blob>;
so that the result will be
var foo = {"World":"Hello\\Test"};
JavaScript will interpret this as an object literal resulting in an object, which is what you want to get anyway. This avoids all the problems with "nested" escape sequences.

You need to add two \\ for every backslash you want to have it displayed. If you're parsing a json, to display 2 backslashes you need to add 4.
// inside a string to be parsed as json
var json = '{"World":"Hello\\\\Test"}'
console.log(JSON.parse(json))
// directly in an object
var object = {"World": "Hello\\Test"}
console.log(object)

try
{
var res = '{"World":"Hello\\\\Test"}';
var s = JSON.parse(res);
console.log(JSON.stringify(s));
} catch(error) {
alert(error);
}

Related

"Fixing" JSON coming out of MySQL

I'm fetching JSON code stored in MySQL and it has extra slashes, which I have to remove in order to parse it in JavaScript, after I print it on the page. Right now I'm doing the following:
$save = str_replace("\n", "<br>", $save); // Replace new line characters with <br>
$save = str_replace('\\"', '"', $save); // top-level JSON
$save = str_replace('\\\\"', '\"', $save); // HTML inside top level JSON
$save = str_replace('\\\\\\\\\\"', '\\\\\"', $save); // HTML inside second level JSON
Here is an example JSON code, as it comes out from MySQL:
{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}
And here is how it's supposed to look in order to get parsed correctly (using jsonlint.com to test):
{"id":2335,"editor":{"selected_shape":"spot-7488"},"general":{"name":"HTML Test","shortcode":"html-test","width":1280,"height":776},"spots":[{"id":"spot-7488","x":9.9,"y":22.6,"default_style":{"use_icon":1},"tooltip_content":{"content_type":"content-builder","plain_text":"<p class=\"test\">Test</p>","squares_json":"{\"containers\":[{\"id\":\"sq-container-293021\",\"settings\":{\"elements\":[{\"settings\":{\"name\":\"Paragraph\",\"iconClass\":\"fa fa-paragraph\"},\"options\":{\"text\":{\"text\":\"<p class=\\\"test\\\">Test</p>\"}}}]}}]}"}}]}
Please note that I have HTML code inside JSON, which is inside another JSON and this is where it gets a bit messy.
My question - is there a function or library for PHP (for JS will work too) which covers all those corner cases, because I'm sure someone will find a way to break the script.
Thanks!
The short answer, which is woefully inadequate, is for you to use stripslashes. The reason this answer is not adequate is that your JSON string might have been escaped or had addslashes called on it multiple times and you would have to call stripslashes precisely once for each time this had happened.
The proper solution is to find out where the slashes are being added and either a) avoid adding the slashes or b) understand why the slashes are there and respond accordingly. I strongly believe that the process that creates that broken JSON is where the problem lies.
Slashes are typically added in PHP in a few cases:
magic_quotes are turned on. This is an old PHP feature which has been removed. The basic idea is that PHP used to auto-escape quotes in incoming requests to let you just cram incoming strings into a db. Guess what? NOT SAFE.
add_slashes has been called. Why call this? Some folks use it as an incorrect means of escaping data before sticking stuff in a db. Others use it to keep HTML from breaking when echoing variables out (htmlspecialchars should probably be used instead). It can also come in handy in a variety of other meta situations when you are defining code in a string.
When escaping data input. The most common escaping function is mysqli_real_escape_string. It's very important to escape values before inserting them in a db to prevent sql injection and other exploits but you should never escape things twice.
So there's a possibility that your code is double-escaping things or that addslashes is getting called or something like magic_quotes is causing the problem, but I suspect it is another problem: some JS code might be supplying this JSON not as a proper JSON string, but one that has been escaped so to define a string within javascript.
If you take your example JSON string above, and slap some quotes around it:
var myJSON = "<put your string here>";
then SURPRISE your javascript is not broken and the var myJSON contains a string that is actually valid JSON and can be parsed into an a valid JSON object:
var myJSON = "{\"id\":2335,\"editor\":{\"selected_shape\":\"spot-7488\"},\"general\":{\"name\":\"HTML Test\",\"shortcode\":\"html-test\",\"width\":1280,\"height\":776},\"spots\":[{\"id\":\"spot-7488\",\"x\":9.9,\"y\":22.6,\"default_style\":{\"use_icon\":1},\"tooltip_content\":{\"content_type\":\"content-builder\",\"plain_text\":\"<p class=\\\"test\\\">Test</p>\",\"squares_json\":\"{\\\"containers\\\":[{\\\"id\\\":\\\"sq-container-293021\\\",\\\"settings\\\":{\\\"elements\\\":[{\\\"settings\\\":{\\\"name\\\":\\\"Paragraph\\\",\\\"iconClass\\\":\\\"fa fa-paragraph\\\"},\\\"options\\\":{\\\"text\\\":{\\\"text\\\":\\\"<p class=\\\\\\\"test\\\\\\\">Test</p>\\\"}}}]}}]}\"}}]}";
console.log(JSON.parse(myJSON)); // this is an actual object
The key here is to examine the point of entry where this JSON arrives in your system. I suspect some AJAX request has created some object and rather than sending valid JSON Of that object, it is sending instead an escaped string of a JSON object.
EDIT:
Here's a simple example of what happens when you have too many encodings. Try running this JS in your browser and observe the console output:
var myObj = {"key":"here is my value"};
console.log(myObj);
var myJSON = JSON.stringify(myObj);
console.log(myJSON);
var doubleEncoded = JSON.stringify(myJSON);
console.log(doubleEncoded);

How to differentiate between a String and JSON [duplicate]

This question already has answers here:
How to test if a string is JSON or not?
(22 answers)
Closed 7 years ago.
I have been working with JSON for quite a while now.
I know that JSON is stringified JavaScript Object.
I also know what makes JSON, as discussed in the below thread.
What is the difference between JSON and Object Literal Notation?
Question: But, I want to know if there is typeof kind of way that would tell me if a given string is JSON or just any other string.
What I have observed so far:
1. var data = {"name":"JS"};
alert(typeof(data)); // object. Agree!
2. // I know this is JSON, by looking at the syntax
var data = '{"name":"JS"}';
alert(typeof(data)); // string.
3. // I know this is just any other string (NOT JSON), by looking at the syntax.
var data = "AnyOtherString";
alert(typeof(data)); // string
Is there any way,in JavaScript, that I could differentiate between Point 2 & Point 3 above. Possibly, something similar to typeof that would tell me if its just a string or a JSON(also a string).?
To see if something is JSON: Try to parse it as JSON.
JSON.parse will throw an exception (which you can trap with try/catch) if it isn't.
function isJSON(str) {
try {
JSON.parse(str);
return true;
} catch (err) {
return false;
}
}
alert(
isJSON('{"name":"JS"}') + " / " + isJSON("AnyOtherString")
);
This may not be fast under large Strings, but is the only sure way:
function isJson(a){
try {
JSON.parse(response);
return true;
} catch(e) {
return false;
}
}
If you are facing large strings, parsing them to JSON can be troublesome, then you could use basic validation, like searching for ':', '{', '}', which could reject some Strings on start, before entering real validation.
Here is some post that resolves it by regexp:
No, JSON is just a string. The only thing you can do is to try to decode the string as JSON. If that succeeds, I suppose it was JSON. If not, it wasn't.
However, it seems worrisome that you need to guess in the first place. If you don't know what data you have, how can you productively work with it? Your application should have certain expectations of what data it holds at any moment and these expectations need to be met. Otherwise you can't write any reliable algorithm to work with that data. You should either know that you have JSON or that you don't.

remove double quotes from Json return data using Jquery

I use JQuery to get Json data, but the data it display has double quotes. It there a function to remove it?
$('div#ListingData').text(JSON.stringify(data.data.items[0].links[1].caption))
it returns:
"House"
How can I remove the double quote? Cheers.
Use replace:
var test = "\"House\"";
console.log(test);
console.log(test.replace(/\"/g, ""));
// "House"
// House
Note the g on the end means "global" (replace all).
For niche needs when you know your data like your example ... this works :
JSON.parse(this_is_double_quoted);
JSON.parse("House"); // for example
The stringfy method is not for parsing JSON, it's for turning an object into a JSON string.
The JSON is parsed by jQuery when you load it, you don't need to parse the data to use it. Just use the string in the data:
$('div#ListingData').text(data.data.items[0].links[1].caption);
Someone here suggested using eval() to remove the quotes from a string. Don't do that, that's just begging for code injection.
Another way to do this that I don't see listed here is using:
let message = JSON.stringify(your_json_here); // "Hello World"
console.log(JSON.parse(message)) // Hello World
I also had this question, but in my case I didn't want to use a regex, because my JSON value may contain quotation marks. Hopefully my answer will help others in the future.
I solved this issue by using a standard string slice to remove the first and last characters. This works for me, because I used JSON.stringify() on the textarea that produced it and as a result, I know that I'm always going to have the "s at each end of the string.
In this generalized example, response is the JSON object my AJAX returns, and key is the name of my JSON key.
response.key.slice(1, response.key.length-1)
I used it like this with a regex replace to preserve the line breaks and write the content of that key to a paragraph block in my HTML:
$('#description').html(studyData.description.slice(1, studyData.description.length-1).replace(/\\n/g, '<br/>'));
In this case, $('#description') is the paragraph tag I'm writing to. studyData is my JSON object, and description is my key with a multi-line value.
You can simple try String(); to remove the quotes.
Refer the first example here: https://www.w3schools.com/jsref/jsref_string.asp
Thank me later.
PS: TO MODs: don't mistaken me for digging the dead old question. I faced this issue today and I came across this post while searching for the answer and I'm just posting the answer.
What you are doing is making a JSON string in your example. Either don't use the JSON.stringify() or if you ever do have JSON data coming back and you don't want quotations, Simply use JSON.parse() to remove quotations around JSON responses! Don't use regex, there's no need to.
I dont think there is a need to replace any quotes, this is a perfectly formed JSON string, you just need to convert JSON string into object.This article perfectly explains the situation : Link
Example :
success: function (data) {
// assuming that everything is correct and there is no exception being thrown
// output string {"d":"{"username":"hi","email":"hi#gmail.com","password":"123"}"}
// now we need to remove the double quotes (as it will create problem and
// if double quotes aren't removed then this JSON string is useless)
// The output string : {"d":"{"username":"hi","email":"hi#gmail.com","password":"123"}"}
// The required string : {"d":{username:"hi",email:"hi#gmail.com",password:"123"}"}
// For security reasons the d is added (indicating the return "data")
// so actually we need to convert data.d into series of objects
// Inbuilt function "JSON.Parse" will return streams of objects
// JSON String : "{"username":"hi","email":"hi#gmail.com","password":"123"}"
console.log(data); // output : Object {d="{"username":"hi","email":"hi#gmail.com","password":"123"}"}
console.log(data.d); // output : {"username":"hi","email":"hi#gmail.com","password":"123"} (accessing what's stored in "d")
console.log(data.d[0]); // output : { (just accessing the first element of array of "strings")
var content = JSON.parse(data.d); // output : Object {username:"hi",email:"hi#gmail.com",password:"123"}" (correct)
console.log(content.username); // output : hi
var _name = content.username;
alert(_name); // hi
}
I had similar situation in a Promise just solved doing a cast as (String)
export async function getUserIdByRole(userRole: string): Promise<string> {
const getRole = userData.users.find((element) => element.role === userRole);
return String (getRole?.id);
}

How can I access JSON.#attribute from an XML Converted on Javascript

I got a JSON converted from XML.
So, how can I get json.#attribute.something.
# <-- this one will make javascript error
I use Javascript.
Making a great exercise of imagination, I suppose you've used jQuery to download some JSON through AJAX and you have an object with a key called "#attribute", such as this:
var foo = {
"#attribute": 33
}
You just need to use square brackets:
console.log(foo["#attribute"])

Parsing JSON with Javascript

I have this JSon string received from an AJAX call:
{status:OK,addresses:[0,1,2,3,4,5]}
To convert it to a JSon object I have this line:
var jsonObj = eval(jsonString);
But an exception is thrown! This one has no message in the exception variable.
I also tried using
{"status":"OK","addresses":[0,1,2,3,4,5]}
And, yet again, an exception is thrown but saying that an unexpected character '&' was found.
I'm using Struts2 and the JSon is received from an action.
Any help will be appreciated.
Thank you
{status:OK,addresses:[0,1,2,3,4,5]}
is not valid JSON because the quotes around status and addresses are missing, and is neither valid JSON nor valid JavaScript since the quotes around OK are missing.
Also, don't use eval to parse JSON - it allows an attacker to execute arbitrary JavaScript in the context of your page. Instead, use the safe alternatives JSON.parse(built-in in modern browsers and other EcmaScript 5 implementations) or JSON2.
Don't use eval: use a proper JSON parser such as JSON2.
You probably have extra content in the response: check that you are not printing anything else out.
This is working for me:
JSON.parse('{ "status" : "OK", "addresses" : [0,1,2,3,4,5]}');
If you want to use eval, then you need to use the second example you posted ({"status":"OK","addresses":[0,1,2,3,4,5]}) and you need to surround the string with parenthesis as such:
var jsonObj = eval( '('+jsonString+')' );
This makes jsonString a valid javascript statement.
With that being said, I encourage you use JSON.parse, as many others have posted. It is far more secure.
You don't have a JSON string. You do have an object literal. You need the names to have quotes.
{"status":OK, "addresses":[0,1,2,3,4,5]}
Based on this comment:
So I verified that when JSon is received from the request, all the " are replaced by " ... could this be the problem?
Yes. A JSON parser expects to receive JSON as input, not HTML encoded JSON.
Two issues to fix:
Add quotes around the "OK" to make it a legal javascript string.
Add parens around the string before sending to eval like this eval("(" + jsonString + ")")';
This:
{status:OK,addresses:[0,1,2,3,4,5]}
would have to be changed to this:
{status:"OK",addresses:[0,1,2,3,4,5]}
to be valid Javascript (note the quotes around "OK").
It should be this to be valid JSON (quotes around the keys too):
{"status":"OK", "addresses":[0,1,2,3,4,5]}
OK all by itself is not a known piece of Javascript without the quotes around it to make it into a Javascript string. In the future, you can test yourself in a small test bed and see what the error is in your favorite javascript debugger:
http://jsfiddle.net/jfriend00/FcSKR/
var jsonString = '{"status":"OK","addresses":[0,1,2,3,4,5]}';
var jsonObj = eval("(" + jsonString + ")");
alert("success");
If you still get an error with {"status":"OK","addresses":[0,1,2,3,4,5]} and the adding of parens before sending to eval, then your data isn't what you think it is and you need to do some debugging to see exactly what is in the response (look at the value in the debugger, put the value into an alert, etc...). There is probably some other stuff in the response that you didn't know would be there.
Note: there are some situations where a JSON parser like JSON.parse() and a legal JSON string is safer than eval() with Javascript that can be anything.

Categories

Resources