Merge pull request #1835 from msaby/fixreplace

Fix regular expression option in replace menu. Closes #1834
This commit is contained in:
Antonin Delpeuch 2018-11-22 16:09:34 +00:00 committed by GitHub
commit ccde661a27
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -139,7 +139,7 @@ DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
// p : a string without beginning and trailing "/" // p : a string without beginning and trailing "/"
// we need a manual check for unescaped / // we need a manual check for unescaped /
// the GREL replace function cannot contain a pattern with unescaped / // the GREL replace() function cannot contain a pattern with unescaped /
// but javascript Regexp accepts it and auto escape it // but javascript Regexp accepts it and auto escape it
var pos = p.replace(/\\\//g,'').indexOf("/"); var pos = p.replace(/\\\//g,'').indexOf("/");
if (pos != -1) { if (pos != -1) {
@ -160,34 +160,34 @@ DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
// 1 characters : \ | 2 characters : \\ // 1 characters : \ | 2 characters : \\
// 1 character : ' | 2 characters : \' // 1 character : ' | 2 characters : \'
// 1 character : " | 2 characters : \" // 1 character : " | 2 characters : \"
// new line | 2 characters : \n // new line or tab | nothing
// tab | 2 characters : \t // other non printable char | nothing
// parameters : // parameters :
// s : a string from an HTML input // s : a string from an HTML input
// Note: it is not possible to insert new lines in HTML input but it is safer to search for them, in case the input field is replaced with a textarea // Note: if the input field is replaced with a textarea, it could be imaginable to escape new lines and tabs as \n and \t
if (typeof s != 'string') { if (typeof s != 'string') {
return ""; return "";
} }
// convert new lines and tabs manually typed in the HTML input into \n and \t, delete other non printable characters, escape \ ' and " // delete new lines, tabs and other non printable characters, and escape \ ' and "
return s.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/[\x00-\x1F\x80-\x9F]/g, '').replace(/'/g, "\\'").replace(/"/g, '\\"') return s.replace(/[\x00-\x1F\x80-\x9F]/g, '').replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/"/g, '\\"')
} }
function escapeInputRegex(s) { function escapeInputRegex(s) {
// if the HTML input is used as a regex pattern // if the HTML input is used as a regex pattern
// suppress new lines and tabs manually typed in the HTML input, and other non printable characters // delete new lines, tabs and other non printable characters
// no need to escape \ or / // no need to escape \ or /
// parameters : // parameters :
// s : a string from a HTML input // s : a string from a HTML input
return (typeof s == 'string') ? s.replace(/[\x00-\x1F\x80-\x9F]/g, '') : "" return (typeof s == 'string') ? s.replace(/[\x00-\x1F\x80-\x9F]/g, '') : ""
} }
function stringToRegex(s) { function escapedStringToRegex(s) {
// converts a plain string to regex, in order to use the i flag // converts a plain string (beforehand escaped with escapeInputString) to regex, in order to use the i flag
// escaping is needed to force the regex processor to interpret every character litteraly // escaping is needed to force the regex processor to interpret every character litteraly
// parameters : // parameters :
// s : a string from a HTML input, preprocessed with escapeInputString // s : a string from a HTML input, preprocessed with escapeInputString
if (typeof s != 'string') { if (typeof s != 'string') {
return ""; return "";
} }
// no need to escape \ : already escaped by escapeInputString // we MUST NOT escape \ : already escaped by escapeInputString
var EscapeCharsRegex = /[-|{}()[\]^$+*?.]/g; var EscapeCharsRegex = /[-|{}()[\]^$+*?.]/g;
// FIXME escaping of / directly by adding / or \/ or // in EscapeCharsRegex don't work... // FIXME escaping of / directly by adding / or \/ or // in EscapeCharsRegex don't work...
return s.replace(EscapeCharsRegex, '\\$&').replace(/\//g, '\\/'); return s.replace(EscapeCharsRegex, '\\$&').replace(/\//g, '\\/');
@ -255,9 +255,14 @@ DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
var find_case_insensitive = elmts.find_case_insensitiveInput[0].checked; var find_case_insensitive = elmts.find_case_insensitiveInput[0].checked;
var find_whole_word = elmts.find_whole_wordInput[0].checked; var find_whole_word = elmts.find_whole_wordInput[0].checked;
replacement_text = escapeReplacementString(replace_dont_escape, replacement_text) replacement_text = escapeReplacementString(replace_dont_escape, replacement_text)
if (find_regex) {
text_to_find = escapeInputRegex(text_to_find);
}
else {
text_to_find = escapeInputString(text_to_find); text_to_find = escapeInputString(text_to_find);
}
if (!find_regex && (find_case_insensitive || find_whole_word)) { if (!find_regex && (find_case_insensitive || find_whole_word)) {
text_to_find = stringToRegex(text_to_find); text_to_find = escapedStringToRegex(text_to_find);
} }
if (find_regex || find_case_insensitive || find_whole_word ) { if (find_regex || find_case_insensitive || find_whole_word ) {
if (!isValidRegexPattern (text_to_find)) { if (!isValidRegexPattern (text_to_find)) {