Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript regex to escape quotes (but not escape already escaped quotes)

I am looking for a JavaScript regex which will escape single quotes but it should not escape single quotes which are already escaped.

like image 818
user1031396 Avatar asked Nov 30 '22 06:11

user1031396


2 Answers

Ideally, you want every match to start exactly where the previous match ended. Otherwise it's too easy to get out of sync with the escape sequences. @outis's regex comes close, but it fails to escape the second single-quote in '\\'. After the first match, it has to match at least one non-backslash and one single-quote, which it can't do. If there are any more characters, it skips ahead and starts matching after the second single-quote.

Try this one instead:

result = subject.replace(/([^'\\]*(?:\\.[^'\\]*)*)'/g, "$1\\'");

This is an example of Friedl's "unrolled loop" pattern:

normal * (special normal *) *

[^'\\]* is the "normal *" part; it gobbles up any number of characters other than single-quotes or backslashes. If the next character is a backslash, \\. ("special") consumes that and the next character (backslash, single-quote, or whatever) and [^'\\]* takes over again. Repeat as needed.

The key point is that the regex never skips ahead and it never backtracks. If it sees a backslash, it always consumes that and the next character, so it never gets out of sync.

like image 128
Alan Moore Avatar answered Dec 06 '22 07:12

Alan Moore


If there are an even number of backslashes, they only quote each other. Thus a character is quoted if it has an odd number of preceding backslashes. Since JS doesn't support lookbehind, you'll need to capture the leading non-backslash and include it in the replacement.

var escquote = /((^|[^\\])(\\\\)*)'/g
"a ' b \' c \\' d".replace(escquote, "$1\\'")

However, if this is for any sort of security purposes, it's the wrong approach for a number of reasons. Firstly, if you're doing this client side, it isn't secure. Second, quoting should be handled when data is sent to a subsystem using the methods provided by the subsystem. For example, if the data is going to a relational database, you should use prepared statements and parameterize the varying data. Prepared statement parameters aren't vulnerale to injection.

like image 39
outis Avatar answered Dec 06 '22 07:12

outis