form-text-sanitizer
Version:
Sanitize strings — expecting text — from html, svg, erb, and mustache expressions.
65 lines (64 loc) • 3.79 kB
JavaScript
const openAngleBracket = /<|%3c|<|�{0,6}60|�{0,6}3c/gisv;
const openAngleBracketMatcher = /[<\q{%3c|<|<|<|<|<|<|<|<|<|<|<|<|<|<|<}]/gisv;
const closedAngleBracket = />|%3e|>|�{0,6}62|�{0,6}3e/gisv;
const closedAngleBracketMatcher = /[>\q{%3e|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>}]/gisv;
const doubleQuoteMatcher = /["\q{%22|"|"|"|"|"|"|"|"|"|"|"|"|"|"|"}]/gisv;
const singleQuoteMatcher = /['\q{%27|&apos|'|'|'|'|'|'|'|'|'|'|'|'|'|'}]/gisv;
const backtickMatcher = /[`\q{%60|&DiacriticalGrave|`|`|`|`|`|`|`|`|`|`|`|`|`|`}]/gisv;
const openBracketMatcher = /[\{\q{%7b|&lcub|{|{|{|{|{|{|{|{|{|{|{|{|{|{}]/gisv;
const closedBracketMatcher = /[\}\q{%7d|&rcub|}|}|}|}|}|}|}|}|}|}|}|}|}|}}]/gisv;
const flags = "gisv";
const htmlSvgErb = "(?:" + openAngleBracketMatcher.source + ";?" + ")" + "+" +
"(?:" +
doubleQuoteMatcher.source + ".*" + doubleQuoteMatcher.source + "|" +
singleQuoteMatcher.source + ".*" + singleQuoteMatcher.source + "|" +
backtickMatcher.source + ".*" + backtickMatcher.source + "|" +
"(?!" + openAngleBracket.source + "|" + closedAngleBracket.source + ")." +
")*" + "(?:" +
".*" + closedAngleBracketMatcher.source + ";?" +
")?";
const htmlSvgErbReg = new RegExp(htmlSvgErb, flags);
const mustache = openBracketMatcher.source + ";?" + openBracketMatcher.source + ".*" + closedBracketMatcher.source + ";?" + closedBracketMatcher.source + ";?";
const mustacheReg = new RegExp(mustache, flags);
const findHTMLSVGERB = (str) => {
const test = htmlSvgErbReg.test(str);
const res = (test ? str.match(htmlSvgErbReg) : []);
const matches = [];
let match = htmlSvgErbReg.exec(str);
while (match != null) {
matches.push(match.index);
match = htmlSvgErbReg.exec(str);
}
return { test, res, matches };
};
const findMustache = (str) => {
const test = mustacheReg.test(str);
const res = (test ? str.match(mustacheReg) : []);
const matches = [];
let match = mustacheReg.exec(str);
while (match != null) {
matches.push(match.index);
match = mustacheReg.exec(str);
}
return { test, res, matches };
};
const checkAndSanitizeString = (str) => {
const htmlCheck = findHTMLSVGERB(str);
let suggestedString = "";
if (htmlCheck.test) {
const lastIdx = htmlCheck.matches.length - 1;
const lastSubstrStart = htmlCheck.matches[lastIdx] + htmlCheck.res[lastIdx].length;
suggestedString = str.substring(0, htmlCheck.matches[0]) + str.substring(lastSubstrStart, str.length);
}
else
suggestedString = str;
const mustacheCheck = findMustache(suggestedString);
if (mustacheCheck.test) {
const lastIdx = mustacheCheck.matches.length - 1;
const lastSubstrStart = mustacheCheck.matches[lastIdx] + mustacheCheck.res[lastIdx].length;
suggestedString = suggestedString.substring(0, mustacheCheck.matches[0]) + suggestedString.substring(lastSubstrStart, str.length);
}
const matches = htmlCheck.res.concat(mustacheCheck.res);
return { originalString: str, suggestedString, matches };
};
export default checkAndSanitizeString;