correctly escaping characters when generating dynamic HTML - javascript

I have the following code in a jsFiddle:
function Start() {
var TheData = 'tes"ss<div></div>t3\'k';
var TheHTML = '<div class="SomeClass">' + TestXSS(TheData) + '</div>';
TheHTML += '<input type="text" id="TheTextBox" value="';
TheHTML += TestXSS(TheData) + '" />';
$('#Dynamic').html(TheHTML);
}
function TestXSS(TheText) {
TheText = TheText.replace('"', '"');
TheText = TheText.replace("'", ''');
TheText = TheText.replace('<', '<');
TheText = TheText.replace('>', '>');
return TheText;
}
As you can see, the HTML is dynamically generated and added to the DOM with jQuery, and there's also a function to escape characters that might cause problems. But in the fiddle, there's still an issue and so I was wondering how to correctly escape characters.
Thanks.

Try
function TestXSS(TheText) {
TheText = TheText.replace(/"/g, '"');
TheText = TheText.replace(/'/g, ''');
TheText = TheText.replace(/</g, '<');
TheText = TheText.replace(/>/g, '>');
return TheText;
}
Demo: Fiddle

TheText.replace('"', '"'); // stops after first match
use g modifier for global match
TheText = TheText.replace(/"/g, '"');
The g modifier is used to perform a global match (find all matches rather than stopping after the first match).`

I'd suggest reducing the number of (unnecessary) calls to replace(), and using a regular expression in concert with a map:
function TestXSS(TheText) {
var charMap = {
39 : '&#39',
34 : '&quot',
60 : '<',
62 : '>'
}
return TheText.replace(new RegExp("['\"<>]",'g'), function(a){
return charMap[a.charCodeAt(0)] || '';
});
}
JS Fiddle demo.
References:
RegExp().
replace().

Related

Loop through text for multiple instances of same string

I have a passage of text, which might have multiple of the same word in it. Whenever this word appears, I want to replace it with itself, but wrapped in a div so that I can apply styles and add some extra text.
I have got this working for the first instance of the word:
var definition = glossaryList[index].definition;
var termStart = textAsLower.search(termAsLower);
var termEnd = term.length + termStart;
var replacedText = addDefinitionToText(textContent, term, definition, termStart, termEnd);
function addDefinitionToText(textContent, term, definition, termStart, termEnd) {
var textStart = textContent.substring(0, termStart);
var termInText = textContent.substring(termStart, termEnd);
var textEnd = textContent.substring(termEnd);
var replacedTerm = '<span class="has-definition">' + termInText;
replacedTerm += '<div class="attached-definition">';
replacedTerm += '<div class="defintion-title">' + term + '</div>';
replacedTerm += '<div class="definition-text">' + definition + '</div>';
replacedTerm += '</div>';
replacedTerm += '</span>';
return textStart + replacedTerm + textEnd;
}
I've tried putting this function into a while loop and counting up, but it is causing me issues and freezing or not returning what I am expecting:
while(something.toLowerCase().search(termAsLower)) {
var something = textAsLower.substring(termEnd);
termStart = something.search(termAsLower);
termEnd = term.length + termStart;
replacedText = addDefinitionToText(something, term, definition, termStart, termEnd);
something = replacedText.substring(termEnd);
}
Does anyone have a solution to this? Ideally I would actually like a different method to .search(), which finds all instances not just the first, but my searches haven't been too fruitful.
Thanks!
You can simply use regex to achieve what you want:
var searchWord = "tag";
var textStr = "HTML tag is used for scripting. Tag can also be self-closing.";
// case-insensitive regex
var re = new RegExp(searchWord, "gi");
textStr = textStr.replace(re, '<' + searchWord + '>');
// case-sensitive search
var re = new RegExp(searchWord, "g");
textStr = textStr.replace(re, '<' + searchWord + '>');
I did something like this before. I split the text by spaces and put that array into foreach and edit. Here's an exapmle code
if(text.includes("http")){
var returnString = '';
text.split(" ").forEach(function(link) {
if(link.includes("http")){
returnString += '<a target="_blank" style="color:white" href="' + link + '">here</a> ';
}else{
returnString += link + " ";
}
});
text = returnString;
A regular expression with the String replace method can solve this fairly easily.
This function will return a new string with the word and definition wrapped.
I have used a template literal to make things a bit cleaner but they are unsupported in IE.
function wrapWordWithDefinition(sentance, word, definition) {
var template = `<div>
<div class="attached-definition">
<div class="defintion-title">${word}</div>
<div class="definition-text">${definition}</div>
</div>
</div>`;
// global and case insensitive
var re = new RegExp(word, 'gi');
return sentance.replace(re, template);
}
var sentance = "This will replace word, when word is encountered";
var myword = "word";
var definition = "The definition of the word";
var result = wrapWordWithDefinition(sentance, myword, definition);
console.log(result)
For further reading on regular expressions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Wrap each word in string with span using regular exp

how to replace each word in text with "span" using regular exp?
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806"
final op = "<span class="word">1:393</span><span class="word">1:838</span><span class="word">3:936</span><span class="word">1:998</span><span class="word">1:139</span>...."
You don't really need a regex for that if the separator is always a single space, just split on the space (or \b if you want a regex), add some markup, and join back together again.
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
var op = text.split(' ').map(function(w) {
return '<span class="word">' + w + '------</span>';
}).join('');
document.body.innerHTML = op;
.word {color : red}
var op = '<span class="word">' + text.split(' ').join('</span><span class="word">') + '</span>'
Using String#replace.
const text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
const result = text.replace(/\d:\d+/g, '<span class="word">$&</span>');
console.log(result);
This is what you need (https://jsfiddle.net/6r005vgf/3/):
var text = "1:393 1:838 3:936 1:998 1:1398 1:1652 1:1718 1:1806";
//var final = "<span class='word'>1:393</span><span class='word'>1:838</span><span class='word'>3:936</span><span class='word'>1:998</span><span class='word'>1:139</span>....";
var final_test = "<span class='word'>" + text.replace(/\s+/g, "</span><span class='word'>") + "</span>";
//alert(final);
alert(final_test);

Custom Valid URL validation using regular expression in Javascript

Here,
I am validating URL with following string which either it should be http/https or ip address along with query string and different parenthesis square bracket [] .
I want to prevent following url parenthesis
2)http://192.0.0.0/b4d2f30f-d617-403a-bb2f-dec755d01192?[publisher[client_id]Id] - Not Allowed
what should be regular expression to prevent [publisher[client_id]Id] sting ?
I'm using following regular expression for above strings
var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
if(!regex .test(str)) {
return false;
} else {
return true;
}
what should be changed code for same?
Please help me for the same.
Try this:
var strings = [
'[publisher[client_id]Id]',
'[publisher_id]'
];
var pattern = /\[.*\[.*\].*\]/;
strings.forEach(function(string){
if(pattern.test(string)) {
console.log(string + " -> matched");
}
else {
console.log(string + " -> not matched");
}
});
try this. the first group return url without parameter (withour your publiser, etc)
sorry didn't read it carefully. try that one and return true if valid
edited
var t1 = "htts:/192.0.0.0/b4d2f30f-d617-403a-bb2f-dec755d01192?[publisher[client_id]]";
var t2 = "https://192.0.0.0/b4d2f30f-d617-403a-bb2f-dec755d01192";
var t3 = "https://192.0.0 .0/b4d2f30f-d617-403a-bb2f-dec755d01192?[publisher[client_id]]";
var t4 = "https://192.0.0 .0/b4d2f30f-d617-403a-bb2f-dec755d01192?name=[publisher[client_id]]";
var t5 = "https://192.0.0 .0/b4d2f30f-d617-403a-bb2f-dec755d01192?foo=bar&name=[publisher[client_id]]";
function check(str) {
var url = /((http[s]?:\/\/){1,1}(\w+[-.\/]{0,1}\w?)*)/g,
p = /([\?\&](\w+=){0,1}\[\w+\[\w+\]\w*\])/g;
/*check for url*/
if (!url.test(str)) {
return "invalid url";
}
/*check for [userid[userid]]*/
return p.test(str) ? "invalid" : "valid";
}
document.body.innerHTML = check(t1) + "</br>";
document.body.innerHTML += check(t2) + "</br>";
document.body.innerHTML += check(t3) + "</br>";
document.body.innerHTML += check(t4) + "</br>";
document.body.innerHTML += check(t5) + "</br>";
regards

Javascript replace special chars { } "

Why does this code fail replacing the special chars:
http://jsfiddle.net/TTfzu/26/
var strOutput = 'aaa { " } ';
strOutput.replace(/{/g, "");
strOutput.replace(/}/g, "");
strOutput.replace(/"/g, "");
document.write( strOutput );
What needs to be changed?
replace doesn't change its argument, it returns a new string. You have to assign the result somewhere otherwise it's lost:
var strOutput = 'aaa { " } ';
strOutput = strOutput.replace(/{/g, "");
strOutput = strOutput.replace(/}/g, "");
strOutput = strOutput.replace(/"/g, "");
document.write( strOutput );
or just use a character class [...] in your regexp:
var strOutput = 'aaa { " } ';
strOutput = strOutput.replace(/[{}"]/g, "");
You will need to catch the result from the replace. (And you can chain your replaces.)
var strOutput = 'aaa { " } ';
strOutput = strOutput.replace(/{/g, "").replace(/}/g, "").replace(/"/g, "");
document.write( strOutput );
Btw you can make it as simple as this:
strOutput = strOutput..replace(/({|"|})/g, "");
As of #Alnitak comment:
strOutput = strOutput..replace(/[{}"]/g, "");
Per other answers, you need to use the result of .replace.
However you don't need three calls, you should be using:
strOutput = strOutput.replace(/[{}"]/g, '');
where the [...] is a character class which matches any individual character in that set. Within such a class the only characters that need to be escaped are ^-]\

Add .html to a string Javascript?

I want to check if a string is ending with ".php" extension, if not I want to add .html at the end. I have already tried various "slice" methods without success.
You can use Regex for that
var string1 = "www.example.com/index";
var newString = !/\.php$/i.test(string1)? string1+".html": string1;
// newString = "www.example.com/index.html"
Use (yourstring + '.html').replace(/\.php\.html$/, '.php') to do that:
var str1 = 'one.php';
var str2 = 'two';
var str3 = '.php.three.php';
var str4 = '.php.hey';
console.log((str1 + '.html').replace(/\.php\.html$/, '.php')); // Prints one.php
console.log((str2 + '.html').replace(/\.php\.html$/, '.php')); // Prints two.html
console.log((str3 + '.html').replace(/\.php\.html$/, '.php')); // Prints .php.three.php
console.log((str4 + '.html').replace(/\.php\.html$/, '.php')); // Prints .php.hey.html
Or perhaps:
function appendHTML(string) {
var html = string;
if (string.lastIndexOf('.php') === (string.length - 4)) {
html += '.html';
}
return html;
}
Well, slice() works ok for this task.
var s = "myfile.php";
if (s.slice(-4) != ".php")
s = s.slice(0, -4) + ".html";
Use regular expression to solve your problem.
/.php$/ is a regular expression that checks to see if a string ends with '.php'
For more information read: http://www.w3schools.com/js/js_obj_regexp.asp
Example Code:
str = "http://abc.com";
str = ( /\.php$/.test( str ) ) ? str : str + '.html'; // this is the line you want.
str === "http://abc.com.html" // returns true
Try something like this
function isPHP(str)
{
return str.substring(str.length - 4) == ".php";
}
Then you could do
str = isPHP(str) ? str : str + ".html";

Categories

Resources