aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Volyntsev <xeioex@nginx.com>2025-07-03 16:53:33 -0700
committerDmitry Volyntsev <xeioexception@gmail.com>2025-07-03 19:06:55 -0700
commitecc237b079a699537351ddc3dd1ade2f96918451 (patch)
tree80fc66349ff89dbd4be47745e4b661eaede1b059
parentd63a9d4b1de36c8279f505bc75d13e304726a8ac (diff)
downloadnjs-master.tar.gz
njs-master.zip
Fixed RegExp compilation after 17124c81.HEADmaster
Previously, heap-buffer-overflow happened due to incorrect copying of [...] regexp parts. Found by OSS-Fuzz.
-rw-r--r--external/njs_regex.c9
-rw-r--r--src/test/njs_unit_test.c16
2 files changed, 24 insertions, 1 deletions
diff --git a/external/njs_regex.c b/external/njs_regex.c
index a0decefd..cd45afc0 100644
--- a/external/njs_regex.c
+++ b/external/njs_regex.c
@@ -177,11 +177,16 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text)
continue;
} else {
- *dst++ = *p;
+ *dst++ = *p++; /* Copy '['. */
+
while (p < end && *p != ']') {
*dst++ = *p++;
}
+ if (p < end) {
+ *dst++ = *p; /* Copy ']'. */
+ }
+
continue;
}
}
@@ -189,6 +194,8 @@ njs_regex_escape(njs_mp_t *mp, njs_str_t *text)
*dst++ = *p;
}
+ njs_assert(dst == text->start + text->length);
+
return NJS_OK;
#else
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index 33472f24..541e3327 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -9556,6 +9556,9 @@ static njs_unit_test_t njs_test[] =
{ njs_str("/["),
njs_str("SyntaxError: Unterminated RegExp \"/[\" in 1") },
+ { njs_str("/[][a"),
+ njs_str("SyntaxError: Unterminated RegExp \"/[][a\" in 1") },
+
{ njs_str("/[\\"),
njs_str("SyntaxError: Unterminated RegExp \"/[\\\" in 1") },
@@ -9591,11 +9594,24 @@ static njs_unit_test_t njs_test[] =
njs_str("/\\]cd/") },
#endif
+ { njs_str("RegExp('[][a')"),
+ njs_str("SyntaxError: "
+ njs_pcre_var("pcre_compile2(\"(?!)[a\") failed: missing terminating ] for character class at \"\"",
+ "pcre_compile(\"[][a\") failed: missing terminating ] for character class")) },
+
+ { njs_str("RegExp('[][a][a')"),
+ njs_str("SyntaxError: "
+ njs_pcre_var("pcre_compile2(\"(?!)[a][a\") failed: missing terminating ] for character class at \"\"",
+ "pcre_compile(\"[][a][a\") failed: missing terminating ] for character class")) },
+
{ njs_str("RegExp('[\\\\')"),
njs_str("SyntaxError: "
njs_pcre_var("pcre_compile2(\"[\\\") failed: \\ at end of pattern at \"\"",
"pcre_compile(\"[\\\") failed: \\ at end of pattern")) },
+ { njs_str("RegExp('[][a]')"),
+ njs_str(njs_pcre_var("/(?!)[a]/", "/[][a]/")) },
+
{ njs_str("RegExp('\\\\0').source[1]"),
njs_str("0") },