I need to concatenate untrusted* data into a javascript string, but I need it to work for all types of strings (single quoted, double quoted, or backtick quoted)
And ideally, I need it to work for multiple string types at once
I could use string replace, but this is usually a bad idea.
I was using JSON.stringify, but this only escapes double quotes, not single or backtick.
Other answers that I've found deal with escaping only a single type of quote at a time (and never backticks).
An example of what I need:
untrustedData = 'a String with \'single quotes\', \"double quotes\" and \`backticks\` in it';
const someJS = `console.log(\`the thing is "${escapingFunctionHere(untrustedString)}"\`)`
someJS will be passed to new Function
* N.B. In my context "untrusted" here doesn't mean potentially malicous, but it does need to cope with quotes, escapes and the like.
I am building javascript code dynamically, the constructed code will not be in any way web-facing. In fact its likely that I am the only one who will use this tool directly or indirectly.
I am happy to accept the minimal associated risks
NOTE TO OTHERS: Be sure you understand the risks before doing this kind of thing.
For those interested, I am writing a parser creator. Given an input ebnf grammar file, it will output a JS class that can be used to parse things.
I really do need to output code here.
If all you need to do is escape single quotes ', double quotes " and backticks `, then using replace to prepend a backslash \ should be enough:
untrustedData.replace(/['"`]/g, '\\$&')
const untrustedData = 'I \'am\' "a `string`"';
console.log(untrustedData);
const escapedData = untrustedData.replace(/['"`]/g, '\\$&');
console.log(escapedData);
Related
I need to read dot ner reesources string in java script as mention below.
var resources = #Html.ResourceStrings("Home_General_", Resources.ResourceManager);
The above line will render all the resources (from Dot net resource file) which start with resource key as "Home_General_"
Some of the values from the resources are like "Hi "XYZ" are you there" i.e The string contains quotes character.
If the string has quotes the above call fails.
The one way to avoid this problem is escape the special character as "Hi \"XYZ\" are you there"
Any other way where we can avoid this, As I don't want to pollute my resource string with lot of escape (\) characters.
You need to Javascript-escape any string when you render it as a Javascript string literal.
You must also remove the outer quotes from the string resource; that should be text, not a half-valid Javascript expression.
Use code like this to retrieve a single resource string:
var resourceXYZ = '#Html.Raw(HttpUtility.JavaScriptStringEncode(Resources.ResourceManager.GetString("Home_General_XYZ")))';
We do the following:
We get the resource string via Resources.ResourceManager.GetString().
We pass the result to HttpUtility.JavaScriptStringEncode to escape any special characters in JavaScript.
We pass the result to Html.Raw() to prevent Razor from applying HTML encoding on this string.
We then output the text enclosed in single quote quaracters into the page.
The function Html.ResourceStrings is not a standard function that is part of MVC. Someone at your place must have written it. If you show us this code, we could tell you how to rewrite it to return valid JavaScript literals.
You could wrap your #Html.ResourcesString(...) with HttpUtility.JavaScriptStringEncode which will handle all escape issues.
var resources = #HttpUtility.JavaScriptStringEncode(Html.ResourceStrings("Home_General_", Resources.ResourceManager));
I am trying to dynamically create a javascript file B using a javascript file A (written in Node.js) by writing a string from A to a .js file B. I want to use regular expressions in the javascript file B. This requires me to put the regex functions for B in a string in A. However, whenever I use the backslash (escape character), file A interprets the regex function immediately, instead of treating it as a string.
Some code to help in understanding my problem:
var mongodata = "Some String with square and curly brackets ]}{]]},]},}{}{{}},{[[][,][,";
mongodata = 'var mongodata = ' + mongodata + ';\n function setData(){mongodata = mongodata.replace(/\[ /g,"").replace(/\] \},/g,"</td></tr>").replace(/\] \}/g,"</td></tr>"); document.getElementById("mongodata").innerHTML = mongodata;}';
That mongodata string is intended to be used as the content of a dynamically created .js file.
I understand the wording of this question may be slightly confusing. Please let me know if more clarification is needed.
In your string, just like the \n character, all the other backslashed expressions are being evaluated, so you must escape the backslashes. In other words, write a RegExp that outputs a RegExp. The proper way of escaping the backslashes themselves is \\\ , but you might need to escape other characters as well to prevent their evaluation.
Perhaps I'm misunderstanding your problem, but maybe put the string being assigned to mongodata in escaped quotes:
var mongodata = "\'Some String with square and curly brackets ]}{]]},]},}{}{{}},{[[][,][,\'";
Bit of a lottery this one. I too don't quite understand your question.
You can escape all of the RegEx special characters (. * ? [ ] Etc). You can also dynamically create RegEx operators using:
var objRegEx = new RegExp( pattern, modifiers );
Like I say, lottery... stab in the dark...
I have the following Javascript code to obtain the inner string from an RegExp:
Function.prototype.method = function (name,func){
this.prototype[name] = func;
return this;
};
RegExp.method('toRawString', function(){
return this.toString().replace(/^.(.*).$/,"$1");
});
The purpose of this, is to avoid in string double quoting. For example, if you have a Windows file path "C:\My Documents\My Folder\MyFile.file", you can use it like the following:
alert(/C:\My Documents\My Folder\MyFile.file/.toRawString());
However it is not working for ""C:\My Documents\My Folder\" since it causes syntax error. The only way to avoid it is to keep double quoting at the end of the string. Thus it will be written
alert(/C:\My Documents\My Folder\\/.toRawString());
The fact is any odd number of back slashes on the end of the string will be an error, so all ending back slashes must be double escaped. It will not be hard to use a multiple line small implementation, but are there any single RegExp solution?
NOTE
When using toRawString the RegExp object for this is usually NOT going to be used for any other purpose except for that method. I just want to use the syntax of RegExp to avoid double back slashes in source code. Unfortunately the ending double slashes cannot be easily avoid. I think another workaround is to force a space at the end but that is another question then.
UPDATE
I finally solved the "another question" and posted the code here.
OK, I get what you're trying to do! It's hacky : )
Try something like:
return this.toString().slice(1, -1).replace(/\\+$/, '\\')
Hope that helps.
If you want to include the double quotes in the string just wrap it with single quotes.
s = '"C:\\My Documents\\My Folder\\MyFile.file"'
console.log(s) // Output => "C:\My Documents\My Folder\MyFile.file"
This produces a syntax error:
/C:\My Documents\/
But that regular expression could be written correctly like this:
/C:\\My Documents\\/
Or like this:
new RegExp("C:\\\\My Documents\\\\")
I think your function is just fine and is returning a correct result. Regular expressions just can't end with an unpaired backslash. It's not that you're double escaping - you're just escaping the escape character.
This would produce an error too:
new RegExp("C:\\My Documents\\")
A regular expression like this, for instance, can't be written without a pair of backslashes:
/C:\\What/
Without the second backslash, \W would be interpreted as a special character escape sequence. So escaping the escape character isn't only necessary at the end. It's required anywhere it might be interpreted as the beginning of an escape sequences. For that reason, it might be a good rule of thumb to always use two backslashes to indicate a backslash literal in a regular expression.
Here is a section of code used by CKEditor on my website:
CKEDITOR.config.IPS_BBCODE = {"acronym":{"id":"8","title":"Acronym","desc":"Allows you to make an acronym that will display a description when moused over","tag":"acronym","useoption":"1","example":"[acronym='Laugh Out Loud']lol[/acronym]", ...
If you scroll to the right just a little, you will see this:
"[acronym='Laugh Out Loud']lol[/acronym]"
I need to store all of the CKEditor code inside a javascript string, but I can't figure out how to do it because the string has both " and ' in it. See the problem? Furthermore, I don't think I can just escape the quotes because I tried doing that and the editor didn't work.
Any idea what I can do?
You might try taking the string and injecting JavaScript escape codes into it. JavaScript can essentially use any unicode value when using the format: \u#### - so, for a ' character, the code is \u0039, and for the " character, the code is \u0034.
So - you could encode your example portion of the string as:
\u0034[acronym=\u0039Laugh Out Loud\u0039]lol[/acronym]\u0034
Alternatively, you could attempt to simply escape the quotes as in:
\"[acronym=\'Laugh Out Loud\']lol[/acronym]\"
The problem here occurs when you wind up with this kind of situation:
"data:{'prop1':'back\\slash'}"
Which, when escaped in this manner, becomes:
"data:{\'prop\':\'back\\\\slash\'}\"
While this is somewhat more readable than the first version - de-serializing it can be a little tricky when going across object-spaces, such as a javascript object being passed to a C# parser which needs to deserialize into objects, then re-serialize and come back down. Both languages use \ as their escape character, and it is possible to get funky scenarios which are brain-teasers to solve.
The advantage of the \u#### method is that only JavaScript generally uses it in a typical stack - so it is pretty easy to understand what part should be unescaped by what application piece.
hmm.. you said you already tried to escape the quotes and it gave problems.
This shouldn't give problems at all, so try this:
$newstring = addslashes($oldstring);
There's no need to use Unicode escape sequences. Just surround your string with double quotes, and put a backslash before any double quotes within the string.
var x = "\"[acronym='Laugh Out Loud']lol[/acronym]\"";
I am generating XML using Javascript. It works fine if there are no special characters in the XML. Otherwise, it will generate this message: "invalid xml".
I tried to replace some special characters, like:
xmlData=xmlData.replaceAll(">",">");
xmlData=xmlData.replaceAll("&","&");
//but it doesn't work.
For example:
<category label='ARR Builders & Developers'>
Thanks.
Consider generating the XML using DOM methods. For example:
var c = document.createElement("category");
c.setAttribute("label", "ARR Builders & Developers");
var s = new XMLSerializer().serializeToString(c);
s; // => "<category label=\"ARR Builder & Developers\"></category>"
This strategy should avoid the XML entity escaping problems you mention but might have some cross-browser issues.
This will do the replacement in JavaScript:
xml = xml.replace(/</g, "<");
xml = xml.replace(/>/g, ">");
This uses regular expression literals to replace all less than and greater than symbols with their escaped equivalent.
JavaScript comes with a powerful replace() method for string objects.
In general - and basic - terms, it works this way:
var myString = yourString.replace([regular expression or simple string], [replacement string]);
The first argument to .replace() method is the portion of the original string that you wish to replace. It can be represented by either a plain string object (even literal) or a regular expression.
The regular expression is obviously the most powerful way to select a substring.
The second argument is the string object (even literal) that you want to provide as a replacement.
In your case, the replacement operation should look as follows:
xmlData=xmlData.replace(/&/g,"&");
xmlData=xmlData.replace(/>/g,">");
//this time it should work.
Notice the first replacement operation is the ampersand, as if you should try to replace it later you would screw up pre-existing well-quoted entities for sure, just as ">".
In addition, pay attention to the regex 'g' flag, as with it the replacement will take place all throughout your text, not only on the first match.
I used regular expressions, but for simple replacements like these also plain strings would be a perfect fit.
You can find a complete reference for String.replace() here.