-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathRegularExpression.js
56 lines (50 loc) · 1.36 KB
/
RegularExpression.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
/**
* Validate a regex, ensures enclosed with delimiters and only supported modifiers by PHP *and* JS
*/
const REGEX_WITH_DELIMITERS = /^\/(.+)\/([smi]{0,3})$/
/**
* Find unescaped slashes within a string
*/
const REGEX_UNESCAPED_SLASH = /(?:^|[^\\])(?:\\\\)*\//
/**
* Check if a regex is valid and enclosed with delimiters
*
* @param {string} input regular expression
* @return {boolean}
*/
export function validateExpression(input) {
// empty regex passes
if (input.length === 0) {
return true
}
// Validate regex has delimters
if (!REGEX_WITH_DELIMITERS.test(input)) {
return false
}
// Check pattern is escaped
const { pattern, modifiers } = splitRegex(input)
if (REGEX_UNESCAPED_SLASH.test(pattern)) {
return false
}
// Check if regular expression can be compiled
try {
;(() => new RegExp(pattern, modifiers))()
return true
} catch (e) {
return false
}
}
/**
* Split an enclosed regular expression into pattern and modifiers
*
* @param {string} regex regular expression with delimiters
* @return {{pattern: string, modifiers: string}} pattern and modifiers
*/
export function splitRegex(regex) {
const [, pattern, modifiers] = regex.match(REGEX_WITH_DELIMITERS) || ['', '', '']
return { pattern, modifiers }
}