JSON Parse causing 'undefined' json values - Javascript - javascript

I have searched far and wide for answers to my problem but I am just not winning, I am hoping someone will be kind enough to offer me some guidance.
My below Javascript code is returning undefined json values:
var req = '{"testId":"12345","ruleId":"678910","rulePassed":true,"testValue":"C:\\ProgramTest\\"}'
var stringified = JSON.stringify(req);
console.log('stringified json ' + stringified);
//json = JSON.parse(JSON.stringify(stringified))
var json = JSON.parse(stringified );
console.log('parsed json ' + json);
//testing different ways of pulling out the data, all undefined
var testId = json["testId"];
var ruleId = json.ruleId;
var testValue = json[testValue];
console.log('testValue ' + testValue);
var rulePassed = Boolean(json[rulePassed]);
njson = '{"testId": "' + testId + '","ruleId": "' + ruleId + '","testValue": "' + testValue + '","rulePassed": ' + rulePassed + '}';
console.log('final json ' + njson);
The complication comes in with the backslash in the testValue property.
If I do not stringify the json first, I receive the following error:
SyntaxError: Unexpected token P in JSON at position 143
As soon as I Stringify however, and then parse, the values come back as undefined.
Does anybody perhaps know what I am doing wrong please?
Thanks

If you know that your data will never properly escape backslashes, a quick solution is the following:
var req_escaped = req.replace(/\\/g, "\\\\") // escape backslashes
JSON.parse(req_escaped)
Basically, make your string JSON compliant and then use the usual parsed method.

replacing the backslashes compiles. also you need to add " around testValue when you get it from the json
var req = '{"testId":"12345","ruleId":"678910","rulePassed":true,"testValue":"C:\\ProgramTest\\"}';
var req_escaped = req.replace(/\\/g, "\\\\") // escape backslashes
var json = JSON.parse(req_escaped);
console.log(json);
var testId = json["testId"];
var ruleId = json.ruleId;
var testValue = json["testValue"];
console.log('testValue ' + testValue);
var rulePassed = Boolean(json[rulePassed]);
njson = '{"testId": "' + testId + '","ruleId": "' + ruleId + '","testValue": "' + testValue + '","rulePassed": ' + rulePassed + '}';
console.log('final json ' + njson);

If you have control over the escaping process, the backslashes path should be escaped as follows:
\\ should be \\\\
The first escape escapes it in the Javascript string literal. The second escape escapes it in the JSON string literal. Credits and more details.
var req = '{"testId":"12345","ruleId":"678910","rulePassed":true,"testValue":"C:\\\\ProgramTest\\\\"}'
console.log(JSON.parse(req))

Related

JSON parser keeps failing on newline even after adding another backslash

So I'm making a messaging platform for a school project, and I'm trying to both protect my database, protect XSS attacks, and also allow every single character, including newlines.
So far, I've got everything covered, except newlines. JSON parser cannot for the live of it parse a simple newline.
I've tried prefixing the newline with another backslash (\\n) but that STILL doesn't work!
What should I do?!
Edit 1: Added code that generates the JSON data
string message = "[";
string uid;
for (int i = 0; i < data.Rows.Count; i++) {
if (StringCipher.ConvertToUnixTimestamp(DateTime.Now.AddMinutes(-5)) > int.Parse(data.Rows[i][5].ToString())) {
queryDelete = "DELETE * FROM Bubbleland WHERE MessageID = " + data.Rows[i][0] + ";";
commandDelete = new OleDbCommand(queryDelete, connection);
commandDelete.ExecuteNonQuery();
} else {
message += "{\"mid\":" + data.Rows[i][0];
if (data.Rows[i][1].ToString() == "")
uid = "user";
else
uid = data.Rows[i][1].ToString();
message += ", \"uid\":\"" + uid;
message += "\", \"name\": \"" + data.Rows[i][2];
message += "\", \"color\": \"" + data.Rows[i][3];
message += "\", \"content\": \"" + data.Rows[i][4];
message += "\"}";
if (i + 1 < data.Rows.Count) {
message += ",";
}
}
}
message += "]";
Edit 2: Added JS processing code
async function fetchMessages() {
$.ajax({
type: "POST",
url: "../ASPX/bubblelandFetch.aspx",
success: function (data) {
console.log(data);
data = JSON.parse(data);
var container = document.getElementById("messages-container");
var uid;
container.innerHTML = "";
console.log(data);
for (var i in data) {
var message = '<div id="' + data[i]["mid"];
message += '" class="message ' + data[i]["color"] + '">';
message += '<div class="profile-container">';
if (data[i]["uid"] == "user")
uid = "/Media/user"
else
uid = "/Media/Profile/" + data[i]["uid"];
message += '<img src="' + uid + '.png"/>';
message += '<span>' + data[i]["name"] + '</span></div>';
message += '<div class="content">' + data[i]["content"] + '</div>';
container.innerHTML += message;
}
},
complete: function () {
setTimeout(fetchMessages, intevral);
}
});
}
After messing around with parsing the string you provided me, I have stumbled across a fix and did further research to understand why this happened in the first place.
To put it simply:
‘Single quotes “escape” single quotes’
“Double quotes ‘escape’ double quotes“
These quotes mean, when using single quotes to create a string literal, you must escape any single quotes with a backslash \ for the string literal to be valid. The same goes for when using double quotes to create a string literal, but escaping double quotes with a backslash.
I didn't recognize this issue at first, even though I knew the problem in the first place and I do this all the time.
I came across this Medium article helps put things together, and I suggest you read it to freshen up on using single/double quotes with string literals.
As it turns out, an unescaped \r was messing up the JSON parser.
Whenever you Shift + Enter, it puts \r\n instead of a simple \n. I had no idea it does this. So in my ASPX backend code, I replace \r\n with <br>.

How to correctly evaluate Javascript string containing JSON.parse expression with special characters?

I need to evaluate a JS expression created in the following way
function createExprs(obj){
var decl = "var i = ";
var value = JSON.stringify(obj);
var exprs = decl + "JSON.parse('" + value + "')";
return exprs;
}
var i = createExprs({1:2});//i = "var i = JSON.parse('{"1":4}')"
eval(i); // works fine
However it fails when the obj contains any special characters
var i = createExprs("today\\.article") \\i="var i = JSON.parse('"today\\.article"')"
eval(i) // Unexpected token . in JSON
You need to escape the ":
"var i = JSON.parse('\"today.article\"')"

Single Quote and Double Quote Append

I am trying to append a single quote and also add double quote, but it shows an error as follows
[ts] ':' expected
"id": " + ' + jsonObject["school_id"] + ' + "
expected output would be something similar as follows
"id" : "'12345'"
You can't just use ' like that.
If you want to include single quotes in the string, enclose them in a string.
const jsonObject = {"school_id": "12345"}
const obj = {"id": "'" + jsonObject["school_id"] + "'"}
console.log(obj);
You could use template strings to easily create it.
let jsonObject = {school_id:"1234"}
let s = `"id" : "'${jsonObject["school_id"]}'"`;
console.log(s)
You can simply use Template Strings:
const obj = { school_id: "1234" }
const str = `"id" : "'${obj["school_id"]}'"`;
I have not worked much with TypeScript, but looks like they are supported:
https://basarat.gitbooks.io/typescript/docs/template-strings.html
please try this to achieve expected result "id" : "'12345'"
var jsonObject = {school_id: 12345}
var a = {"id": '\'' + jsonObject['school_id'] + '\''}
console.log (a)
var school_id = '12345';
school_id = "'"+school_id+"'";
school_id = '"'+school_id+'"';
console.log(school_id);
You can do like this but make sure you know the use before doing it. don't code blindly.

Regex mapping in Firefox context menu contentScript

I am developing context menu add-on for Firefox. I am trying to get the selectedText and validate if it is a number. If it is a number i am using that number value to process further.
But, i got stuck at a point where i am trying to replace [(,)] using regex in javascript replace method.
Following is the code which fails to map any number starting/ending with ( or ):
var menuItemLRG = contextMenu.Item({
label: "LRG",
data: "http://myurl/&val=:",
contentScript: 'self.on("click", function (node, data) {' +
' var selectedText = window.getSelection().toString();' +
' var formattedText1 = selectedText.trim();' +
' var formattedText2 = formattedText1.replace(/^[,\[\]()]*/g,"");' +
' var formattedText3 = formattedText2.replace(/[,\[\]()]*$/g,"");' +
' console.log(formattedText3); '+
' var regExp = new RegExp(/^[0-9]+$/);' +
' if (regExp.test(formattedText3) == true) {' +
' console.log("URL to follow :"+data+formattedText3);' +
' window.open(data+formattedText3);' +
' } '+
'});'
});
Above code fails to replace ( or ) in sample inputs: (5663812, 11620033).
But, a vanilla test like the following succeeds:
<script>
var str = "(2342423,])";
var tmpVal1 = str.replace(/^[,\[\]()]*/g,"");
var tmpVal2 = tmpVal1.replace(/[,\[\]()]*$/g,"");
var regExp = new RegExp(/^[0-9]+$/);
if (regExp.test(tmpVal2) == true) {
alert(tmpVal2);
}
</script>
After many trial and error found the issue. When we try to escape a character inside a single quotes we need to add one more escape for the escape character to get recognized, otherwise the single escape \] will be considered as ] which leads to abrupt ending of of the regex pattern.
In this case:
' var formattedText2 = formattedText1.replace(/^[,\[\]()]*/g,"");'
is decoded as :
var formattedText2 = formattedText1.replace(/^[,[]()]*/g,"");
instead of as:
var formattedText2 = formattedText1.replace(/^[,\[\]()]*/g,"");
So, by adding one more escape character for an escape character resolved the pattern correctly:
' var formattedText2 = formattedText1.replace(/^[,\\[\\]()]*/g,"");'
Sorry for wasting your time in analyzing the cause, if any.

The regex test in jQuery's parseJSON returns false - why?

I don't understand why the test in jQuery's parseJSON function:
/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "#")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
.replace(/(?:^|:|,)(?:\s*\[)+/g, ""))
returns false for the string:
{"TermTitle":"some Title"}
The test in http://www.jsonlint.com/ tells me that the string {"TermTitle":"some Title"} is valid JSON, but when I try to pass it into $.parseJSON(opData) the parseJSON function fails...
I also tested just this /^[\],:{}\s]*$/.test... function separately in Firebug with the mentioned string.
[edit]
Ok, code:
var json = '{"TermTitle":"some Title"}';
var obj = $.parseJSON(json);
alert('obj = ' + obj + ' and obj.TermTitle = ' + obj.TermTitle);
works also for me.
But in my case where I have the following in my JavaScript:
function GetTerm($iInd) {
$.ajax({
type: "POST",
url: "get_term.php",
data: {
id: $iInd
},
success: function(data){
ProcessFetchedTerm(data);
}
});
//If I tried adding dataType: "json" then it would stop working at all.
}
function ProcessFetchedTerm(opData) {
alert ("In ProcessFetchedTerm, data: '" + opData + "'");
alert ("typeof opData: " + typeof opData);
alert ("Replacement result of the regex function: " +
opData.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "#").
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").
replace(/(?:^|:|,)(?:\s*\[)+/g, ''));
alert ("Result of the regex function: " +
/^[\],:{}\s]*$/.
test(opData.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "#").
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").
replace(/(?:^|:|,)(?:\s*\[)+/g, '')));
var oTerm = $.parseJSON(opData);
alert('oTerm = ' + oTerm + ' and oTerm.TermTitle = ' + oTerm.TermTitle);
}
and in get_term.php I have:
echo json_encode(
array(
"TermTitle"=>"some Title"
)
);
The alerts return:
In ProcessFetchedTerm, data: '{"TermTitle":"some Title"}'
typeof opData: string
Replacement result of the regex function: {]:]}
Result of the regex function: false
The last alert is not shown
[edit 2]
I rewrote the beginning of my function ProcessFetchedTerm to
function ProcessFetchedTerm(opData) {
var json = '{"TermTitle":"some Title"}';
alert ("In ProcessFetchedTerm, opData: '" + opData + "' json: '" + json + "'");
var oTerm = $.parseJSON(json);
the alert puts out:
In ProcessFetchedTerm, opData: '{"TermTitle":"some Title"}' json: '{"TermTitle":"some Title"}'
So the strings are equal and in case the next line is var oTerm = $.parseJSON(json); it works but if next line is var oTerm = $.parseJSON(opData); it does not work.
So what could be hidden inside this (presumably) string object opData that prevents it from working?
Running this code:
var json = '{"TermTitle":"some Title"}';
var obj = $.parseJSON(json);
alert('obj = ' + obj + ' and obj.TermTitle = ' + obj.TermTitle);
works for me (with jQuery 1.4). The problem must be elsewhere in your code. What is the exact code you are running when the parseJSON method fails?
Edit (response to posted code):
Why are you doing the functionality of your 3rd and 4th alert? I would guess that that is changing your opData value. Try adding your first alert right before your parseJSON call and see what it is there.
It returns "false" because it doesn't match. The "replace" calls transform that JSON string into `{]:]}', which does not match the regex.
[edit] oh durrr yes it does match; well I don't know what your problem is. Why do you think it returns "false"?

Categories