p++;
lexer->start = p;
- flags = njs_regexp_flags(&p, lexer->end, 0);
+ flags = njs_regexp_flags(&p, lexer->end);
if (njs_slow_path(flags < 0)) {
njs_parser_syntax_error(parser, "Invalid RegExp flags \"%*s\"",
start = string.start;
- re_flags = njs_regexp_flags(&start, start + string.length, 1);
- if (njs_slow_path(re_flags < 0)) {
+ re_flags = njs_regexp_flags(&start, start + string.length);
+ if (njs_slow_path(re_flags < 0
+ || (size_t) (start - string.start) != string.length))
+ {
njs_syntax_error(vm, "Invalid RegExp flags \"%V\"", &string);
return NJS_ERROR;
}
njs_regexp_flags_t
-njs_regexp_flags(u_char **start, u_char *end, njs_bool_t bound)
+njs_regexp_flags(u_char **start, u_char *end)
{
u_char *p;
njs_regexp_flags_t flags, flag;
- flags = 0;
+ flags = NJS_REGEXP_NO_FLAGS;
for (p = *start; p < end; p++) {
-
switch (*p) {
-
case 'g':
flag = NJS_REGEXP_GLOBAL;
break;
flag = NJS_REGEXP_MULTILINE;
break;
- case ';':
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- case ',':
- case ')':
- case ']':
- case '}':
- case '.':
- if (!bound) {
- goto done;
+ default:
+ if (*p >= 'a' && *p <= 'z') {
+ goto invalid;
}
- /* Fall through. */
-
- default:
- goto invalid;
+ goto done;
}
if (njs_slow_path((flags & flag) != 0)) {
typedef enum {
NJS_REGEXP_INVALID_FLAG = -1,
+ NJS_REGEXP_NO_FLAGS = 0,
NJS_REGEXP_GLOBAL = 1,
NJS_REGEXP_IGNORE_CASE = 2,
NJS_REGEXP_MULTILINE = 4,
njs_int_t njs_regexp_init(njs_vm_t *vm);
njs_int_t njs_regexp_create(njs_vm_t *vm, njs_value_t *value, u_char *start,
size_t length, njs_regexp_flags_t flags);
-njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end,
- njs_bool_t bound);
+njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end);
njs_regexp_pattern_t *njs_regexp_pattern_create(njs_vm_t *vm,
u_char *string, size_t length, njs_regexp_flags_t flags);
njs_int_t njs_regexp_match(njs_vm_t *vm, njs_regex_t *regex,
/* RegExp. */
- { njs_str("/./x"),
- njs_str("SyntaxError: Invalid RegExp flags \"x\" in 1") },
-
{ njs_str("/"),
njs_str("SyntaxError: Unterminated RegExp \"/\" in 1") },
{ njs_str("/\\\n/"),
njs_str("SyntaxError: Unterminated RegExp \"/\\\" in 1") },
+ { njs_str("/./x"),
+ njs_str("SyntaxError: Invalid RegExp flags \"x\" in 1") },
+
+ { njs_str("/./.exec === RegExp.prototype.exec"),
+ njs_str("true") },
+
+ { njs_str("/./['exec'] === RegExp.prototype.exec"),
+ njs_str("true") },
+
{ njs_str("/^[A-Za-z0-9+/]{4}$/.test('////')"),
njs_str("true") },
{ njs_str("new RegExp('', 'x')"),
njs_str("SyntaxError: Invalid RegExp flags \"x\"") },
+ { njs_str("new RegExp('', 'g ')"),
+ njs_str("SyntaxError: Invalid RegExp flags \"g \"") },
+
+ { njs_str("new RegExp('', '')"),
+ njs_str("/(?:)/") },
+
+ { njs_str("new RegExp('', {toString:()=>'g'})"),
+ njs_str("/(?:)/g") },
+
{ njs_str("RegExp({})"),
njs_str("/[object Object]/") },