Angular 9 template interpolation removing backslashes - javascript

I need to render a string on the page with double backslash "\\" but Angular removes one from the temaplte, treating it like a regular expression.
An example of the issue is here:
https://codepen.io/bental/pen/xxZdYZv
I have also tried escaping with and without DomSanitizer but can't seem to make it work.
I don't want to manipulate the data as it's coming from the backend and can't account for every possibility

If you don't need IE/Opera support, you can use String.raw (note that you need to use backticks instead of double quotes for it to work as intended)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw
this.sanitizer.bypassSecurityTrustHtml(String.raw`Double backslashes are being removed -> \\`);

put \\\\ every \\ represents one \
this.sanitizer.bypassSecurityTrustHtml("Double backslashes are being removed -> \\\\")

Related

When is the HTML attribute backslash escaped as a JavaScript string?

I noticed that backslash is escaped when I get "attribute value including backslash" with JavaScript in the following code.
console.log(document.getElementById("test").getAttribute("class")); // -> \A
console.log(document.getElementById("test").getAttribute("class").replace("\\A", "\A")); // -> A
console.log(document.getElementById("test").dataset.b); // -> \B
console.log(document.getElementById("test").dataset.b.replace("\\B", "\B")); // -> B
<div id="test" class="\A" data-b="\B"></div>
The backslash is treated as a special character in JavaScript, and two backslashes (\\) represent one backslash (\).
The result of the above code means that when getting the attribute value with JavaScript using getAttribute(), one backslash (\) is escaped to two backslashes (\\) at somewhere.
However, in the specification, it seems that the corresponding process is not applied.
Question
In which process of getAttributes() the backslash of HTML attribute is escaped (\ -> \\)?
There's a difference between string literals (which require escaping) and string values from other places (like html, ajax, etc), which are what they look like. Only when converted to literals (ex: JSON.stringify, some console views, etc) do JS strings have backslash escaping. The escape is an output formatting artifact; internally, there are no escapes in the sequence of characters.
HTML doesn't need the same escaping on blackslashes, due to different roots of the standard. An attribute isn't "converted" to one with escaped backslashes unless it's formatted as a string literal. That would happen at a stage between the string and it's visible output. You can use alert() instead of console.log() to see the string as it really is. I believe that specifically for the console, the
goal is to be more helpful to developers than accurate to the internals.

How to prevent regex characters from being changed after page is rendered?

I'am stuck after searching and trying several tests, but just can't figure out how to fix the following issue.
I use these characters \x3c, \x3e and \x22 in a regEx and save is in a variable in *.component.ts but when I use the variable in the markup/HTML, it turns it into <, > and ". the result is that my Pattern doesn't work as expected.
Here is one of test on regex101.com and as you can see it works as it should be:
^(?=.*[a-zA-Z\d!\x22#$%&\'()*+,.:;\x3c=\x3e?#[\]^_`{|}~/\\-])[A-Za-z\d!\x22#$%&\'()*+,.:;\x3c=\x3e?#[\]^_`{|}~/\\-]{8,50}$
How can I prevent this and keep the characters as they are in the original when the page is rendered? Is it a behavior of TypeScript or JavaScript browser engine or what? Any hint would be great.
First of all, you need to use double backslashes to introduce literal backslashes into the regex patterns. I.e. if you write "\x22" as a string literal, it is in fact a mere ". So, to define \x22 in a string literal, write "\\x22".
Then, you have
^(?=.*[a-zA-Z\d!\x22#$%&\'()*+,.:;\x3c=\x3e?#[\]^_`{|}~/\\-])[A-Za-z\d!\x22#$%&\'()*+,.:;\x3c=\x3e?#[\]^_`{|}~/\\-]{8,50}$
The lookahead here is redundant because it requires the same set of chars as is required by the consuming part. The lookahead can be removed, or better replaced with the one you need, (?=[^A-Z]*[A-Z]), requiring at least 1 uppercase ASCII letter:
^(?=[^A-Z]*[A-Z])[A-Za-z\d!\x22#$%&\'()*+,.:;\x3c=\x3e?#[\]^_`{|}~/\\-]{8,50}$
As a string literal:
"^(?=[^A-Z]*[A-Z])[A-Za-z\\d!\\x22#$%&'()*+,.:;\\x3c=\\x3e?#[\\]^_`{|}~/\\\\-]{8,50}$"
See the regex demo.

Write HTML Special Character into a Variable

$("<h2/>", {"class" : "wi wi"+data.today.code}).text(" " + data.city + data.today.temp.now + "F").appendTo(custom_example);
Hi there, I'm trying to alter the code above to add the degrees icon just before the (F)arenheit marker. I've tried entering + html("°") + but it doesn't work. My JS is pretty rough and I was hoping I could get a quick answer here before I spent too long trying and failing. Thanks!
I want the end result to print something like: Encinitas 65°F
Special characters are characters that must be escaped by a backslash\, like:
Single quote \'
Double quote \"
Backslash \\
The degree ° is not a special character, you can just write it, as it is.
Edit: If you want to use the unicode of °F, just write: '\u2109'.
Escape Special Characters JavaScript
JavaScript uses the \ (backslash) as an escape characters for:
\' single quote
\" double quote
\ backslash
\n new line
\r carriage return
\t tab
\b backspace
\f form feed
\v vertical tab (IE < 9 treats '\v' as 'v' instead of a vertical tab
('\x0B').
If cross-browser compatibility is a concern, use \x0B instead of \v.)
\0 null character (U+0000 NULL) (only if the next character is not a
decimal digit; else it’s an octal escape sequence)
Note that the \v and \0 escapes are not allowed in JSON strings.
First of all the degree character needs not to be escaped. So simply entering "°F" should do the job.
However, if you are in doubt with the codepage of your JS code you could use a JavaScript escape sequence. JS escape sequences are quite different from HTML escapes. The do not support decimal values at all. So first of all you have to convert 176 to hex: b0. The correctly escaped equivalent to "°F" is "\xb0F". It will work too and is more robust with respect to codepage issues of you platform's source editor.
If you really want to assign HTML code you need to use the .html() function. But this is mutual exclusive to .text(). So in this case all of your content needs to be HTML rather than plain text. Otherwise an HTML injection vulnerability arises. I.e. you need to properly escape angle brackets and some other symbols in data.city and maybe data.today.temp.now as well.
JS itself has no built-in function to escape HTML. But JQuery provides a trick: $('<div/>').text(data.city).html() will return appropriately escaped HTML. See HTML-encoding lost when attribute read from input field for more details.
I would recommend not to use .html() unless you really need it, e.g. if you want to apply styles or formatting to parts of the text only.

How to use quotes within quotes properly

If you create an HTML element with JS using a string like the following, how can you add the extra quotes required within an onclick event? Since I have already exhausted double and single quotes, is there an elegant way of making this work?
var foo_td="<td onclick='window.open('newpage.html', '_blank')'>Open Page</td>";
You need to replace innermost single quotes ' with double quotes " and escape them with single backslash \, like this:
var foo_td="<td onclick='window.open(\"newpage.html\", \"_blank\")'>Open Page</td>";
Demo
Why escape quotes at first place
This is because when the onclick event will be fired on this td and if there are no quotes (if quotes not escaped), then it will look for a variable named newpage.html and _blank and give an error because these variables (most likely) won't exist.
Why not only single backslash with single quote
Single-backslash will only escape the string for the evaluation of this string expresion, and by the time this value is stored in a string it will ignore this backslash.
Why not double backslash with single quote
By the time nodes are rendered on DOM (can check this on Developer Tools of your browser), its attribute values are enclosed inside a double quote rather than a single quote. So, it will be rendered as this and hence give an error.
<div onclick="window.open(\" newpage.html\',="" \'_blank\')'="">Open Page</div>
So, based on three reasons given above you should always escape double quote if you want to pass a string parameter to a function call from an attribute.

How do I use \ in a JavaScript string without escaping?

I have a string that is automatically generated by some code that encodes a Google Static Map polyline set of longitude,latitude. However, it places these pesky backslashes in the string which tries to escape the character after it.
enc:{eggEhwnQDYOCZuDv#q#H}#v#k#^v#TQh#Aw#j#AJJ#CZKA?LNZ[RUEALDDCRC#AJBBCJ\FAEACC?GM?K#GDGDEJC#BDADBFB#F#HANGH?DB#D\W|#g#QIZm#I#YoAO
I am not putting the encode directly into the HTML (where it would be fine) but instead using JavaScript to do it so this polyline encode gets put into a variable like so:
mapcoords:"path=color:0x00000000|fillcolor:0xFF9999|enc:{eggEhw`nQDYOCZuDv#q#H}#v#k#^v#TQh#`Aw#j#AJJ#CZKA?LNZ[RUEALDDCRC#AJBBCJ\FAEACC?GM?K#GDGDEJC#BDADBFB#F#HANGH?DB#D\W|#g#QIZm#I#YoAO"
Any suggestions how I go around the escaping? I've looked for the ampersand symbol for backslash but it seems one does not exist (if it would even help). So I am not sure how else to go about this.
You have to escape the backslash with a backslash like this:
var some_string = "my string with a backslash here: \\ ";
Most editors today have a find/replace function that you can use to replace a single backslash with two backslashes. If you use Notepad++ you can use CTRL+H to access this function, but as I said, most recent editors and IDE's have this function.
All you need to do is escape the escape character, so you simply get \\ instead of a single \. You will have to do this replacement wherever it is you're outputting that string to the client.

Categories

Resources