diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/config/config.nim | 8 | ||||
-rw-r--r-- | src/js/regex.nim | 35 |
2 files changed, 39 insertions, 4 deletions
diff --git a/src/config/config.nim b/src/config/config.nim index b546ce3c..dfcb63c4 100644 --- a/src/config/config.nim +++ b/src/config/config.nim @@ -183,11 +183,11 @@ proc getSiteConfig*(config: Config, jsctx: JSContext): seq[SiteConfig] = images: sc.images ) if sc.url.isSome: - conf.url = opt(compileRegex(sc.url.get, 0)) + conf.url = opt(compileMatchRegex(sc.url.get)) elif sc.host.isSome: - conf.host = opt(compileRegex(sc.host.get, 0)) + conf.host = opt(compileMatchRegex(sc.host.get)) for rule in sc.third_party_cookie: - conf.third_party_cookie.add(compileRegex(rule, 0).get) + conf.third_party_cookie.add(compileMatchRegex(rule).get) if sc.rewrite_url.isSome: let fun = jsctx.eval(sc.rewrite_url.get, "<siteconf>", JS_EVAL_TYPE_GLOBAL) @@ -201,7 +201,7 @@ proc getSiteConfig*(config: Config, jsctx: JSContext): seq[SiteConfig] = proc getOmniRules*(config: Config, jsctx: JSContext): seq[OmniRule] = for rule in config.omnirule: - let re = compileRegex(rule.match, 0) + let re = compileMatchRegex(rule.match) var conf = OmniRule( match: re.get ) diff --git a/src/js/regex.nim b/src/js/regex.nim index d1ec34a5..eb6ef80f 100644 --- a/src/js/regex.nim +++ b/src/js/regex.nim @@ -68,6 +68,41 @@ proc compileRegex*(buf: string, flags: int): Result[Regex, string] = regex.bytecode = bytecode return ok(regex) +func countBackslashes(buf: string, i: int): int = + var j = 0 + for i in countdown(i, 0): + if buf[i] != '\\': + break + inc j + return j + +# ^abcd -> ^abcd +# efgh$ -> efgh$ +# ^ijkl$ -> ^ijkl$ +# mnop -> ^mnop$ +proc compileMatchRegex*(buf: string): Result[Regex, string] = + if buf.len == 0: + return compileRegex(buf, 0) + if buf[0] == '^': + return compileRegex(buf, 0) + if buf[^1] == '$': + # Check whether the final dollar sign is escaped. + if buf.len == 1 or buf[^2] != '\\': + return compileRegex(buf, 0) + let j = buf.countBackslashes(buf.high - 2) + if j mod 2 == 1: # odd, because we do not count the last backslash + return compileRegex(buf, 0) + # escaped. proceed as if no dollar sign was at the end + if buf[^1] == '\\': + # Check if the regex contains an invalid trailing backslash. + let j = buf.countBackslashes(buf.high - 1) + if j mod 2 != 1: # odd, because we do not count the last backslash + return err("unexpected end") + var buf2 = "^" + buf2 &= buf + buf2 &= "$" + return compileRegex(buf2, 0) + proc compileSearchRegex*(str: string): Result[Regex, string] = # Parse any applicable flags in regex/<flags>. The last forward slash is # dropped when <flags> is empty, and interpreted as a character when the |