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>.
Related
I have this script in javascript.
socket.onmessage = function (event) {
var theDiv = document.getElementById("cli");
var JSONObject = JSON.parse(event.data);
if(JSONObject.event === "console output") {
theDiv.innerHTML += "<div>" + JSONObject['args'] + "</div>";
}
};
the outcome of JSONObject['args'] is this:
>[2K [16:10:47] [Server thread/INFO]: [Server] test
The string is this
{"event":"console output","args":["\u003e\u001b[2K\r[16:10:47] [Server thread/INFO]: [Server] test"]}
How can i remove this from the string \u003e\u001b[2K\r?
i tried this but it doesn't work
socket.onmessage = function (event) {
var theDiv = document.getElementById("cli");
var JSONObject = JSON.parse(event.data.replaceAll("\u003e\u001b[2K\r", ""));
if(JSONObject.event === "console output") {
theDiv.innerHTML += "<div>" + JSONObject['args'] + "</div>";
}
};
How can I make it work? like this
{"event":"console output","args":["[16:10:47] [Server thread/INFO]: [Server] test"]}
Do the replacement after parsing the JSON.
You need to use map() because JSONObject.args is an array.
theDiv.innerHTML += "<div>" + JSONObject.args.map(arg => arg.replaceAll( "\u003e\u001b[2K\r", "")) + "</div>";
Otherwise you need to escape all the backslashes, so they'll be treated literally.
var JSONObject = JSON.parse(event.data.replaceAll("\\u003e\\u001b[2K\\r", ""));
But it's generally a bad idea to manipulate the JSON string directly, as you may invalidate the JSON. It's usually best to parse the JSON and then deal with the resulting object/array.
You can try to convert toString() and then remove the value
JSONObject['args'].toString().replace('\u003e\u001b[2K\r', '')
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))
I swear i tried figuring this out myself all day, but my regex-foo is just not that good.
I'm trying to create a small parser function to convert strings with urls to html coded and tags
I know how complex a regex can be trying to figure out which urls to covert to what from a big string, so what I did is simply prefix the string to covert with a flag to tell the parser how to format it, and post fix it with the ";" char to tell the parser where that particular URL ends. This way the parser has lesser guest work to do resulting in easier to regex-match and faster for execution. I really dont need a generalize match and replace all.
So my formatting is as follows, where "X" is the url string:
For URLs it will be url=X;
For IMAGES it will be img=X;
so anything in between my prefix and post fix must be converted accordingly..
So for example, for images in my document, the string could be:
click this image img=http://example.com/image1.jpg;
and i need that converted to
click this image <a href="http://example.com/image1.jpg" target="_blank">
<img class="img img-responsive" src="http://example.com/image1.jpg"/></a>
I am able to do this easily in PHP buy preg_match() function
preg_match('/\img=(.+?)\;/i', $item_des, $matches)
here's the code block:
I decided to push this routine to the browser instead of the backend (PHP) so i need similar or better JS solution.
Hoping anyone can help here, thanks!
try code below:
var str = "click this image img=http://example.com/image1.jpg;image2 img=http://example.com/image2.jpg;"
var phrases = str.split(';');
var totalRes = '';
phrases.forEach(function(str){
totalRes += processPhrase(str);
});
console.log(totalRes);
function processPhrase(str) {
var img = str.split('img=')
var res = '';
if (img.length > 1) { //img=X
var url = img[1].replace(';', '');
res = img[0] + "<a href='" + url + "' target='_blank'><img src='" + url + "'/></a>";
} else {
var url = str.split('url=');
//Do for url=X here
}
console.info(res);
return res;
}
You can use this regexp /(img|url)=(.+?);/g:
(img|url) : the type, should be grouped so we will know what to do with the value
= : literal "="
(.+?) : a number of characters (use the non-greedy ? so it will match as fewer as possible)
; : literal ";"
Read more about non-greedy regexps here.
Example:
var str = "click this image img=http://i.imgur.com/3wY30O4.jpg?a=123&b=456; and check this URL url=http://google.com/;. Bye!";
// executer is an object that has functions that apply the changes for each type (you can modify the functions for your need)
var executer = {
"url": function(e) {
return '<a target="_blank" href="' + e + '">' + e + '</a>';
},
"img": function(e) {
return '<a target="_blank" href="' + e + '"><img src="' + e + '"/></a>';
}
}
var res = str.replace(/(img|url)=(.+?);/g, function(m, type, value) {
return executer[type](value); // executer[type] will be either executer.url or executer.img, then we pass the value to that function and return its returned value
});
console.log(res);
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.
As part of a homework I am trying to implement a JavaScript console similar to the one available in Firebug in a browser environment. From what I've picked up, eval() seems to be the easiest way to do this. However, my code runs into some problems on even very basic user input. For example:
var number = 5;
Causes a syntax error rather than just evaluating to undefined like it would in Firebug. Because of this I can't seem to declare variables at all inside the eval string. If I do something more simple like:
3 + 4 * Math.PI
It works correctly. I have tried to find an example of someone using eval() on a string containing a variable declaration, and I just can't seem to find anyone doing this.
Do I need to parse the user input completely using regular expressions before compiling it into a new string for eval()?
Can eval() understand semicolons as line breaks? I can't find people using these either.
function runMiniFirebug() {
var userInput = document.getElementById("user-input").value;
try {
var userOutput = eval('(' + userInput + ')');
document.getElementById("js-output").innerHTML += '<p class="input">>>>' + userInput + '<p>';
document.getElementById("js-output").innerHTML += '<p class="ouput">' + userOutput + '<p>';
}
catch(error) {
document.getElementById("js-output").innerHTML += '<p class="input">>>>' + userInput + '<p>';
document.getElementById("js-output").innerHTML += '<p class="error">' + error.message + '<p>';
}
}
EDIT:
So it seems the added parens are causing the error. This is a section from my instructors slides. Is the information incorrect, or am I just interpreting it incorrectly?
Strings that are delimited with { ... }
– You have to add extra parens so that JavaScript will know that the
braces are for object literals, not for delimiting statements.
• It never hurts to do this, so add parens routinely
– var test2 = "{ firstName: 'Jay', lastName: 'Sahn' }";
– var person = eval("(" + test2 + ")");
var userOutput = eval('(' + userInput + ')');
Why are you wrapping with parentheses? This creates the statement
(var number = 5;)
which is invalid syntax.
Simply remove the '(' + and + ')'.
As for your edit, that is referring to only evaluating single expressions. var number = 5; is not an expression, nor is alert(1 + 1); alert(2 + 2);. Wrapping either in parentheses will cause an error.