Escape single quote with JavaScript - javascript

I am aware with escaping special characters in HTML.
But, I am still asking this as I have come across a situation.
I have a JSP, in which I am not allowed put validation on input. Users are entering special characters to test.
Input string:
'##$%
When I am displaying from database, I am using
<%= StringEscapeUtils.escapeHtml(map[i].get("text").toString())%>
where "map" is an array of Hashmap. This works fine.
The problem comes when I need to pass this string to JavaScript using
<input type="Button"
onclick="onEdit('<%= StringEscapeUtils.escapeHtml(map[i].get("text").toString())%>',
'<%= strShortCut%>','<%= map[i].get("uid")%>')" value="Edit">
The string becomes ''##$%'.
How do I escape a single quote?

If you would be using Java, maybe you can do the below in Java.
import org.apache.commons.lang.StringEscapeUtils;
...
String result = StringEscapeUtils.escapeJavaScript(jsString);

Just prepend every single quote with a backslash. Like the following:
StringEscapeUtils.escapeHtml(map[i].get("text").toString()).replace("\'","\\'")
But your problem is not only in the single quote. There is also the double quote (") and the backslash itself (\).
Use the same technique as shown before. You can also use regular expressions, but I showed you the simplest way.
To check the escape characters, look at the URL http://docs.oracle.com/javase/tutorial/java/data/characters.html.

Related

Escaping several quote levels in vues templates

Going through the Vue online guide, I ran into something that looks like a quote escaping problem. More specifically, I am toying around with the example provided in chapter components->events.
The template in my component looks like
"<div class=\"blog-post\">\
<h3>{{ post.title }}</h3>\
<button #click=\"$emit(\\\"enlarge-text\\\")\" >Enlarge text</button>\
<div v-text=\"post.content\"></div>\
</div>"
And instead of the expected button, I get the string
")" >Enlarge text
I managed to circumvent my issue by replacing the two occurrences of the double escape \\\" by single quotes, but I have the feeling there is something I am missing here. Can you help me to understand what is happening here or provide me pointers towards the relevant doc?
Any explanation is welcome.
As I'm sure you're aware, escaping is used to include characters literally within text that would otherwise be interpreted as having a special meaning. Establishing which characters have special meaning requires us to look at the 'channels' that will be interpreting that text and then select a suitable escaping mechanism for those channels.
In this case the text will be interpreted by 3 channels...
As a JavaScript string literal.
By the Vue template compiler, which has a format very similar to HTML.
Expressions within the template, such as binding expressions, will be treated as JavaScript, potentially including yet more JavaScript string literals.
JavaScript string literals use the \ character to introduce escape sequences. However, the HTML-like syntax used for Vue templates do not. As for HTML they use entities prefixed with &.
So, working backwards, we first need to consider how we escape the expressions within the template. In this case that is $emit("enlarge-text"). As the string "enlarge-text" doesn't contain any special characters we don't need to apply any escaping. Easy so far.
Then we need to escape the template 'HTML'. Now we do run into problems because the #click attribute is delimited with double-quotes and its value contains double-quotes. Obviously we could dodge the issue by using different types of quotes but if we instead hit the problem head-on we'd need to use & entities to escape those quotes. i.e. " for ". That gives us:
<button #click="$emit("enlarge-text")">Enlarge text</button>
I believe this is where the escaping in the question goes wrong as it attempts to use \ escaping to escape the attribute value.
If we were using SFCs then that would be sufficient. But for a template written as a string literal we've still got one more level of escaping to apply, using \. The original quotes around enlarge-text are no longer present so they don't require any further escaping but we still have the quotes around the attribute. That gives us:
"<button #click=\"$emit("enlarge-text")\">Enlarge text</button>"
However, all that said, the usual conventions when specifying string templates are:
Use backticks for the template string itself, giving better multi-line support.
Use double-quotes around attributes.
Use single-quotes for strings within expressions.
Obviously there are cases where that isn't possible, such as if you want to use backticks within an expression, but if you stick to those conventions as much as possible you usually won't need to escape anything. When you do it'll also be a lot simpler to perform the escaping as you aren't using the same delimiters at all three levels.
You could use template literal / template string for this:
let tpl = `<div class="blog-post">
<h3>{{ post.title }}</h3>
<button #click="$emit('enlarge-text')">Enlarge text</button>
<div v-text="post.content"></div>
</div>`;
Not only does it read better, it is way more maintanable than multiple escaped quotes.
You can wrap enlarge-text with single quotes. Like this:
<button #click=\"$emit('enlarge-text')\">Enlarge text</button>

RegExp for remove first and last char and turn ending double slashes into single

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.

Too many quotes within quotes -- what to do?

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]\"";

How to add "\" character in JSON?

I want to add JSON data with the following string value:
json = "d:\xyz\abc";
This value is coming from a database at runtime. When I am going to display it in datatable, JSON formatting error is displayed. My requirement is that the above value will be displayed as it is in the datatable. Please help.
Escape it with another \:
var json = "d:\\xyz\\abc";
You'd better use a JSON library for your programming language. You don't retrieve database values directly with jquery, aren't you?
So, you'd use something like JSON.escape(my_string_from_db), or, in Ruby language I usually do my_string.to_json.
This will automatically escape everything that needs to be escaped.
Change to this:
json = "d:\\xyz\\abc";
See this question for further information
\ is the escape character in JavaScript strings, it gives special meaning to the character following the slash. Like \t is a tab character, \n is a new line. To put a backslash literal you'll need to use \\
The first backslash says the next character is going to be special, the following backslash says "oh, it's just a backslash."

Escaping quotes from Rails Variables when using them for Javascript?

I am having problems when trying to use a rails variable within javascript code.
For example, I might define a link_to_remote, with parameter
:complete => "alert('my_var');"
If my_var = "I'm testing.", then the javascript code will break due to the single quote closing the code prematurely. If I try using escape_javascript(my_var) so that the quote gets turned into \', it doesn't seem to fix the problem.
I've noticed that when you try alert('I\'m testing'); there's a problem, but if you do alert('I\\'m testing'), it works. Since escape_javascript only turns ' into \', rather than \\', does somebody have a suggestion for how to handle this?
Thanks!
Eric
when you try alert('I\'m testing'); there's a problem
Backslash is also an escape in Ruby strings! So the string literal:
"alert('I\'m testing');"
means the string:
alert('I'm testing');
the backslash is gone already before JavaScript gets a look at it. When you are writing a JavaScript string literal inside a Ruby string literal you need to escape the escape, \\, to get a real \ that will then, in JavaScript, escape the apostrophe.
escape_javascript correctly generates the backslash for JavaScript, if a backslash was included in its input. But again, if you're writing a string literal, you have to escape the backslash to get a real backslash:
escape_javascript("\b") -> this is a backspace character!
escape_javascript("\\b") -> this is backslash-then-letter-b;
escaped for JavaScript literal to double-backslash-then-b.
So, this is fine:
"'"+escape_javascript(myvar)+"'"
alternatively, you can use a JSON encoder to create the JavaScript string literal including the surrounding quotes.

Categories