Welcome! Log In Create A New Profile

Advanced

[njs] Handling zero byte characters inside RegExp pattern strings.

Dmitry Volyntsev
June 04, 2019 05:46AM
details: https://hg.nginx.org/njs/rev/f57cf6b5233a
branches:
changeset: 998:f57cf6b5233a
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Tue Jun 04 12:45:06 2019 +0300
description:
Handling zero byte characters inside RegExp pattern strings.

Fixed heap-buffer-overflow in RegExp.prototype.source.
This closes #168 issue on Github.

diffstat:

njs/njs_regexp.c | 31 +++++++++++++++++++++++++++----
njs/test/njs_unit_test.c | 24 ++++++++++++++++++++++++
2 files changed, 51 insertions(+), 4 deletions(-)

diffs (118 lines):

diff -r 2054b8410a28 -r f57cf6b5233a njs/njs_regexp.c
--- a/njs/njs_regexp.c Thu May 30 20:05:14 2019 +0300
+++ b/njs/njs_regexp.c Tue Jun 04 12:45:06 2019 +0300
@@ -207,17 +207,19 @@ njs_regexp_create(njs_vm_t *vm, njs_valu


/*
- * PCRE with PCRE_JAVASCRIPT_COMPAT flag rejects regexps with
+ * 1) PCRE with PCRE_JAVASCRIPT_COMPAT flag rejects regexps with
* lone closing square brackets as invalid. Whereas according
* to ES6: 11.8.5 it is a valid regexp expression.
*
+ * 2) escaping zero byte characters as "\u0000".
+ *
* Escaping it here as a workaround.
*/

nxt_inline njs_ret_t
njs_regexp_escape(njs_vm_t *vm, nxt_str_t *text)
{
- size_t brackets;
+ size_t brackets, zeros;
u_char *p, *dst, *start, *end;
nxt_bool_t in;

@@ -225,6 +227,7 @@ njs_regexp_escape(njs_vm_t *vm, nxt_str_
end = text->start + text->length;

in = 0;
+ zeros = 0;
brackets = 0;

for (p = start; p < end; p++) {
@@ -244,14 +247,24 @@ njs_regexp_escape(njs_vm_t *vm, nxt_str_

case '\\':
p++;
+
+ if (p == end || *p != '\0') {
+ break;
+ }
+
+ /* Fall through. */
+
+ case '\0':
+ zeros++;
+ break;
}
}

- if (!brackets) {
+ if (!brackets && !zeros) {
return NXT_OK;
}

- text->length = text->length + brackets;
+ text->length = text->length + brackets + zeros * nxt_length("\\u0000");

text->start = nxt_mp_alloc(vm->mem_pool, text->length);
if (nxt_slow_path(text->start == NULL)) {
@@ -283,6 +296,16 @@ njs_regexp_escape(njs_vm_t *vm, nxt_str_
if (p == end) {
goto done;
}
+
+ if (*p != '\0') {
+ break;
+ }
+
+ /* Fall through. */
+
+ case '\0':
+ dst = nxt_cpymem(dst, "\\u0000", 6);
+ continue;
}

*dst++ = *p;
diff -r 2054b8410a28 -r f57cf6b5233a njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Thu May 30 20:05:14 2019 +0300
+++ b/njs/test/njs_unit_test.c Tue Jun 04 12:45:06 2019 +0300
@@ -5564,6 +5564,9 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("/]cd/"),
nxt_string("/\\]cd/") },

+ { nxt_string("RegExp('\\\\0').source[1]"),
+ nxt_string("0") },
+
{ nxt_string("']'.match(/]/)"),
nxt_string("]") },

@@ -12812,6 +12815,27 @@ static njs_unit_test_t njs_regexp_test[

{ nxt_string("/[\\uFDE0-\\uFFFD]/g; export default 1"),
nxt_string("SyntaxError: Illegal export statement in 1") },
+
+ { nxt_string("RegExp(RegExp('\x00]]')).test('\x00]]')"),
+ nxt_string("true") },
+
+ { nxt_string("RegExp('\0').test('\0')"),
+ nxt_string("true") },
+
+ { nxt_string("RegExp('\x00').test('\0')"),
+ nxt_string("true") },
+
+ { nxt_string("RegExp('\x00\\\\x00').source"),
+ nxt_string("\\u0000\\x00") },
+
+ { nxt_string("/\\\0/"),
+ nxt_string("/\\\\u0000/") },
+
+ { nxt_string("RegExp('\\\\\\0').source"),
+ nxt_string("\\\\u0000") },
+
+ { nxt_string("RegExp('[\0]').test('\0')"),
+ nxt_string("true") },
};


_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Handling zero byte characters inside RegExp pattern strings.

Dmitry Volyntsev 365 June 04, 2019 05:46AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 299
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready