(pattern: string, flags: string)
| 1087 | // https://tc39.github.io/ecma262/#sec-literals-regular-expression-literals |
| 1088 | |
| 1089 | private testRegExp(pattern: string, flags: string): RegExp | null { |
| 1090 | // The BMP character to use as a replacement for astral symbols when |
| 1091 | // translating an ES6 "u"-flagged pattern to an ES5-compatible |
| 1092 | // approximation. |
| 1093 | // Note: replacing with '\uFFFF' enables false positives in unlikely |
| 1094 | // scenarios. For example, `[\u{1044f}-\u{10440}]` is an invalid |
| 1095 | // pattern that would not be detected by this substitution. |
| 1096 | const astralSubstitute = '\uFFFF'; |
| 1097 | let tmp = pattern; |
| 1098 | const self = this; |
| 1099 | |
| 1100 | if (flags.indexOf('u') >= 0) { |
| 1101 | tmp = tmp |
| 1102 | // Replace every Unicode escape sequence with the equivalent |
| 1103 | // BMP character or a constant ASCII code point in the case of |
| 1104 | // astral symbols. (See the above note on `astralSubstitute` |
| 1105 | // for more information.) |
| 1106 | .replace(/\\u\{([0-9a-fA-F]+)\}|\\u([a-fA-F0-9]{4})/g, ($0, $1, $2) => { |
| 1107 | const codePoint = parseInt($1 || $2, 16); |
| 1108 | if (codePoint > 0x10FFFF) { |
| 1109 | self.throwUnexpectedToken(Messages.InvalidRegExp); |
| 1110 | } |
| 1111 | if (codePoint <= 0xFFFF) { |
| 1112 | return String.fromCharCode(codePoint); |
| 1113 | } |
| 1114 | return astralSubstitute; |
| 1115 | }) |
| 1116 | // Replace each paired surrogate with a single ASCII symbol to |
| 1117 | // avoid throwing on regular expressions that are only valid in |
| 1118 | // combination with the "u" flag. |
| 1119 | .replace( |
| 1120 | /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, |
| 1121 | astralSubstitute |
| 1122 | ); |
| 1123 | } |
| 1124 | |
| 1125 | // First, detect invalid regular expressions. |
| 1126 | try { |
| 1127 | RegExp(tmp); |
| 1128 | } catch (e) { |
| 1129 | this.throwUnexpectedToken(Messages.InvalidRegExp); |
| 1130 | } |
| 1131 | |
| 1132 | // Return a regular expression object for this pattern-flag pair, or |
| 1133 | // `null` in case the current environment doesn't support the flags it |
| 1134 | // uses. |
| 1135 | try { |
| 1136 | return new RegExp(pattern, flags); |
| 1137 | } catch (exception) { |
| 1138 | /* istanbul ignore next */ |
| 1139 | return null; |
| 1140 | } |
| 1141 | } |
| 1142 | |
| 1143 | private scanRegExpBody(): string { |
| 1144 | let ch = this.source[this.index]; |
no test coverage detected