NJS_TEST262=YES
NJS_OPENSSL=YES
+
+NJS_PCRE=YES
NJS_TRY_PCRE2=YES
NJS_CONFIGURE_OPTIONS=
--test262=*) NJS_TEST262="$value" ;;
--no-openssl) NJS_OPENSSL=NO ;;
+
+ --no-pcre) NJS_PCRE=NO ;;
--no-pcre2) NJS_TRY_PCRE2=NO ;;
--help)
# Copyright (C) Igor Sysoev
# Copyright (C) NGINX, Inc.
-njs_found=no
-NJS_HAVE_PCRE2=NO
+NJS_PCRE_CFLAGS=
+NJS_PCRE_LIB=
-if [ $NJS_TRY_PCRE2 = YES ]; then
- if /bin/sh -c "(pcre2-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then
+NJS_HAVE_PCRE=NO
- NJS_PCRE_CFLAGS=`pcre2-config --cflags`
- NJS_PCRE_LIB=`pcre2-config --libs8`
+if [ $NJS_PCRE = YES ]; then
- njs_feature="PCRE2 library"
- njs_feature_name=NJS_HAVE_PCRE2
- njs_feature_run=no
- njs_feature_incs="-DPCRE2_CODE_UNIT_WIDTH=8 $NJS_PCRE_CFLAGS"
- njs_feature_libs=$NJS_PCRE_LIB
- njs_feature_test="#include <pcre2.h>
+ njs_found=no
- int main(void) {
- pcre2_code *re;
+ if [ $NJS_TRY_PCRE2 = YES ]; then
+ if /bin/sh -c "(pcre2-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then
- re = pcre2_compile((PCRE2_SPTR)\"\",
- PCRE2_ZERO_TERMINATED, 0,
- NULL, NULL, NULL);
- return (re == NULL);
- }"
+ NJS_PCRE_CFLAGS=`pcre2-config --cflags`
+ NJS_PCRE_LIB=`pcre2-config --libs8`
- . auto/feature
+ njs_feature="PCRE2 library"
+ njs_feature_name=NJS_HAVE_PCRE2
+ njs_feature_run=no
+ njs_feature_incs="-DPCRE2_CODE_UNIT_WIDTH=8 $NJS_PCRE_CFLAGS"
+ njs_feature_libs=$NJS_PCRE_LIB
+ njs_feature_test="#include <pcre2.h>
- if [ $njs_found = yes ]; then
- NJS_HAVE_PCRE2=YES
- echo " + PCRE2 version: `pcre2-config --version`"
- fi
- fi
-fi
-
-if [ $njs_found = no ]; then
- if /bin/sh -c "(pcre-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then
-
- NJS_PCRE_CFLAGS=`pcre-config --cflags`
- NJS_PCRE_LIB=`pcre-config --libs`
+ int main(void) {
+ pcre2_code *re;
- njs_feature="PCRE library"
- njs_feature_name=NJS_HAVE_PCRE
- njs_feature_run=no
- njs_feature_incs=$NJS_PCRE_CFLAGS
- njs_feature_libs=$NJS_PCRE_LIB
- njs_feature_test="#include <pcre.h>
+ re = pcre2_compile((PCRE2_SPTR)\"\",
+ PCRE2_ZERO_TERMINATED, 0,
+ NULL, NULL, NULL);
+ return (re == NULL);
+ }"
- int main(void) {
- pcre *re;
+ . auto/feature
- re = pcre_compile(NULL, 0, NULL, 0, NULL);
- if (re == NULL)
- return 1;
- return 0;
- }"
- . auto/feature
+ if [ $njs_found = yes ]; then
+ NJS_HAVE_PCRE=YES
+ echo " + PCRE2 version: `pcre2-config --version`"
+ fi
+ fi
+ fi
- if [ $njs_found = yes ]; then
- echo " + PCRE version: `pcre-config --version`"
+ if [ $njs_found = no ]; then
+ if /bin/sh -c "(pcre-config --version)" >> $NJS_AUTOCONF_ERR 2>&1; then
+
+ NJS_PCRE_CFLAGS=`pcre-config --cflags`
+ NJS_PCRE_LIB=`pcre-config --libs`
+
+ njs_feature="PCRE library"
+ njs_feature_name=NJS_HAVE_PCRE
+ njs_feature_run=no
+ njs_feature_incs=$NJS_PCRE_CFLAGS
+ njs_feature_libs=$NJS_PCRE_LIB
+ njs_feature_test="#include <pcre.h>
+
+ int main(void) {
+ pcre *re;
+
+ re = pcre_compile(NULL, 0, NULL, 0, NULL);
+ if (re == NULL)
+ return 1;
+ return 0;
+ }"
+ . auto/feature
+
+ if [ $njs_found = yes ]; then
+ NJS_HAVE_PCRE=YES
+ echo " + PCRE version: `pcre-config --version`"
+ fi
fi
fi
-fi
-if [ $njs_found = no ]; then
- echo
- echo $0: error: no PCRE library found.
- echo
- exit 1;
+ if [ $njs_found = no ]; then
+ echo
+ echo $0: error: no PCRE library found.
+ echo
+ exit 1;
+ fi
+
fi
src/njs_async.c \
"
-NJS_LIB_PCRE_SRCS=" \
- src/njs_pcre.c \
-"
-
-NJS_LIB_PCRE2_SRCS=" \
- src/njs_pcre2.c \
-"
-
NJS_LIB_TEST_SRCS=" \
src/test/lvlhsh_unit_test.c \
src/test/random_unit_test.c \
src/test/njs_benchmark.c \
"
-if [ "$NJS_HAVE_PCRE2" = "YES" ]; then
- NJS_LIB_SRCS="$NJS_LIB_SRCS $NJS_LIB_PCRE2_SRCS"
-else
- NJS_LIB_SRCS="$NJS_LIB_SRCS $NJS_LIB_PCRE_SRCS"
+if [ "$NJS_PCRE" = "YES" ]; then
+ NJS_LIB_SRCS="$NJS_LIB_SRCS external/njs_regex.c"
fi
NJS_TS_SRCS=$(find ts/ -name "*.d.ts" -o -name "*.json")
echo " + using CC: \"$CC\""
echo " + using CFLAGS: \"$NJS_CFLAGS $NJS_CC_OPT $CFLAGS\""
echo
-echo " + using PCRE library: $NJS_PCRE_LIB"
+
+if [ $NJS_HAVE_PCRE = YES ]; then
+ echo " + using PCRE library: $NJS_PCRE_LIB"
+fi
if [ $NJS_HAVE_READLINE = YES ]; then
echo " + using readline library: $NJS_READLINE_LIB"
/*
* Copyright (C) Igor Sysoev
+ * Copyright (C) Dmitry Volyntsev
* Copyright (C) NGINX, Inc.
*/
#include <njs_main.h>
+#ifdef NJS_HAVE_PCRE2
+
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
+
+
+static const u_char* njs_regex_pcre2_error(int errcode, u_char buffer[128]);
+
+#else
+
#include <pcre.h>
static njs_regex_generic_ctx_t *regex_context;
+#endif
+
njs_regex_generic_ctx_t *
njs_regex_generic_ctx_create(njs_pcre_malloc_t private_malloc,
njs_pcre_free_t private_free, void *memory_data)
{
+#ifdef NJS_HAVE_PCRE2
+
+ return pcre2_general_context_create(private_malloc, private_free,
+ memory_data);
+#else
+
njs_regex_generic_ctx_t *ctx;
ctx = private_malloc(sizeof(njs_regex_generic_ctx_t), memory_data);
}
return ctx;
+
+#endif
}
njs_regex_compile_ctx_t *
njs_regex_compile_ctx_create(njs_regex_generic_ctx_t *ctx)
{
+#ifdef NJS_HAVE_PCRE2
+
+ return pcre2_compile_context_create(ctx);
+
+#else
+
return ctx;
+
+#endif
}
-/*
- * 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.
- */
njs_int_t
njs_regex_escape(njs_mp_t *mp, njs_str_t *text)
{
+#ifdef NJS_HAVE_PCRE2
+
+ return NJS_OK;
+
+#else
+
+ /*
+ * 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.
+ */
+
size_t brackets, zeros;
u_char *p, *dst, *start, *end;
njs_bool_t in;
text->length = dst - text->start;
return NJS_OK;
+
+#endif
}
njs_regex_compile(njs_regex_t *regex, u_char *source, size_t len,
njs_regex_flags_t flags, njs_regex_compile_ctx_t *cctx, njs_trace_t *trace)
{
+#ifdef NJS_HAVE_PCRE2
+
+ int ret;
+ u_char *error;
+ size_t erroff;
+ njs_uint_t options;
+ u_char errstr[128];
+
+ options = PCRE2_ALT_BSUX | PCRE2_MATCH_UNSET_BACKREF;
+
+ if ((flags & NJS_REGEX_IGNORE_CASE)) {
+ options |= PCRE2_CASELESS;
+ }
+
+ if ((flags & NJS_REGEX_MULTILINE)) {
+ options |= PCRE2_MULTILINE;
+ }
+
+ if ((flags & NJS_REGEX_STICKY)) {
+ options |= PCRE2_ANCHORED;
+ }
+
+ if ((flags & NJS_REGEX_UTF8)) {
+ options |= PCRE2_UTF;
+ }
+
+ regex->code = pcre2_compile(source, len, options, &ret, &erroff, cctx);
+
+ if (njs_slow_path(regex->code == NULL)) {
+ error = &source[erroff];
+
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre_compile2(\"%s\") failed: %s at \"%s\"",
+ source, njs_regex_pcre2_error(ret, errstr), error);
+
+ return NJS_DECLINED;
+ }
+
+ ret = pcre2_pattern_info(regex->code, PCRE2_INFO_CAPTURECOUNT,
+ ®ex->ncaptures);
+
+ if (njs_slow_path(ret < 0)) {
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre2_pattern_info(\"%s\", PCRE2_INFO_CAPTURECOUNT) failed: %s",
+ source, njs_regex_pcre2_error(ret, errstr));
+
+ return NJS_ERROR;
+ }
+
+ ret = pcre2_pattern_info(regex->code, PCRE2_INFO_BACKREFMAX,
+ ®ex->backrefmax);
+
+ if (njs_slow_path(ret < 0)) {
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre2_pattern_info(\"%s\", PCRE2_INFO_BACKREFMAX) failed: %s",
+ source, njs_regex_pcre2_error(ret, errstr));
+
+ return NJS_ERROR;
+ }
+
+ /* Reserve additional elements for the first "$0" capture. */
+ regex->ncaptures++;
+
+ if (regex->ncaptures > 1) {
+ ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMECOUNT,
+ ®ex->nentries);
+
+ if (njs_slow_path(ret < 0)) {
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMECOUNT) failed: %s",
+ source, njs_regex_pcre2_error(ret, errstr));
+
+ return NJS_ERROR;
+ }
+
+ if (regex->nentries != 0) {
+ ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMEENTRYSIZE,
+ ®ex->entry_size);
+
+ if (njs_slow_path(ret < 0)) {
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMEENTRYSIZE)"
+ " failed: %s", source,
+ njs_regex_pcre2_error(ret, errstr));
+
+ return NJS_ERROR;
+ }
+
+ ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMETABLE,
+ ®ex->entries);
+
+ if (njs_slow_path(ret < 0)) {
+ njs_alert(trace, NJS_LEVEL_ERROR,
+ "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMETABLE) "
+ "failed: %s", source,
+ njs_regex_pcre2_error(ret, errstr));
+
+ return NJS_ERROR;
+ }
+ }
+ }
+
+ return NJS_OK;
+
+#else
+
int ret, err, erroff;
char *pattern, *error;
void *(*saved_malloc)(size_t size);
regex_context = NULL;
return ret;
+
+#endif
}
njs_regex_match_data_t *
njs_regex_match_data(njs_regex_t *regex, njs_regex_generic_ctx_t *ctx)
{
+#ifdef NJS_HAVE_PCRE2
+
+ if (regex != NULL) {
+ return pcre2_match_data_create_from_pattern(regex->code, ctx);
+ }
+
+ return pcre2_match_data_create(0, ctx);
+
+#else
+
size_t size;
njs_uint_t ncaptures;
njs_regex_match_data_t *match_data;
}
return match_data;
+
+#endif
}
njs_regex_match_data_free(njs_regex_match_data_t *match_data,
njs_regex_generic_ctx_t *ctx)
{
- ctx->private_free(match_data, ctx->memory_data);
-}
+#ifdef NJS_HAVE_PCRE2
+ pcre2_match_data_free(match_data);
-static void *
-njs_pcre_malloc(size_t size)
-{
- return regex_context->private_malloc(size, regex_context->memory_data);
-}
+#else
+ ctx->private_free(match_data, ctx->memory_data);
-static void
-njs_pcre_free(void *p)
-{
- regex_context->private_free(p, regex_context->memory_data);
+#endif
}
njs_regex_match(njs_regex_t *regex, const u_char *subject, size_t off,
size_t len, njs_regex_match_data_t *match_data, njs_trace_t *trace)
{
+#ifdef NJS_HAVE_PCRE2
+
+ int ret;
+ u_char errstr[128];
+
+ ret = pcre2_match(regex->code, subject, len, off, 0, match_data, NULL);
+
+ if (ret < 0) {
+ if (ret == PCRE2_ERROR_NOMATCH) {
+ return NJS_DECLINED;
+ }
+
+ njs_alert(trace, NJS_LEVEL_ERROR, "pcre2_match() failed: %s",
+ njs_regex_pcre2_error(ret, errstr));
+ return NJS_ERROR;
+ }
+
+ return ret;
+
+#else
+
int ret;
ret = pcre_exec(regex->code, regex->extra, (const char *) subject, len,
}
return ret;
+
+#endif
}
size_t
njs_regex_capture(njs_regex_match_data_t *match_data, njs_uint_t n)
{
+#ifdef NJS_HAVE_PCRE2
+
+ size_t c;
+
+ c = pcre2_get_ovector_pointer(match_data)[n];
+
+ if (c == PCRE2_UNSET) {
+ return NJS_REGEX_UNSET;
+ }
+
+ return c;
+
+#else
+
return match_data->captures[n];
+
+#endif
+}
+
+#ifdef NJS_HAVE_PCRE2
+
+static const u_char *
+njs_regex_pcre2_error(int errcode, u_char buffer[128])
+{
+ pcre2_get_error_message(errcode, buffer, 128);
+
+ return buffer;
+}
+
+#else
+
+static void *
+njs_pcre_malloc(size_t size)
+{
+ return regex_context->private_malloc(size, regex_context->memory_data);
+}
+
+
+static void
+njs_pcre_free(void *p)
+{
+ regex_context->private_free(p, regex_context->memory_data);
}
+
+#endif
+
+
$ngx_addon_dir/ngx_js_fetch.h"
NJS_SRCS="$ngx_addon_dir/ngx_js.c \
$ngx_addon_dir/ngx_js_fetch.c \
+ $ngx_addon_dir/ngx_js_regex.c \
$ngx_addon_dir/../external/njs_webcrypto_module.c"
if [ $HTTP != NO ]; then
$ngx_addon_dir/../build/libnjs.a: $NGX_MAKEFILE
cd $ngx_addon_dir/.. \\
&& if [ -f build/Makefile ]; then \$(MAKE) clean; fi \\
- && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-pcre2 \\
- && \$(MAKE)
+ && CFLAGS="\$(CFLAGS)" CC="\$(CC)" ./configure --no-openssl --no-pcre \\
+ && \$(MAKE) libnjs
END
--- /dev/null
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <ngx_config.h>
+
+#if (NGX_PCRE2)
+
+#define NJS_HAVE_PCRE2 1
+
+#endif
+
+#include "../external/njs_regex.c"
+++ /dev/null
-
-/*
- * Copyright (C) Dmitry Volyntsev
- * Copyright (C) NGINX, Inc.
- */
-
-
-#include <njs_main.h>
-
-#define PCRE2_CODE_UNIT_WIDTH 8
-#include <pcre2.h>
-
-
-static const u_char* njs_regex_pcre2_error(int errcode, u_char buffer[128]);
-
-
-njs_regex_generic_ctx_t *
-njs_regex_generic_ctx_create(njs_pcre_malloc_t private_malloc,
- njs_pcre_free_t private_free, void *memory_data)
-{
- return pcre2_general_context_create(private_malloc, private_free,
- memory_data);
-}
-
-
-njs_regex_compile_ctx_t *
-njs_regex_compile_ctx_create(njs_regex_generic_ctx_t *ctx)
-{
- return pcre2_compile_context_create(ctx);
-}
-
-
-njs_int_t
-njs_regex_escape(njs_mp_t *mp, njs_str_t *text)
-{
- return NJS_OK;
-}
-
-
-njs_int_t
-njs_regex_compile(njs_regex_t *regex, u_char *source, size_t len,
- njs_regex_flags_t flags, njs_regex_compile_ctx_t *ctx, njs_trace_t *trace)
-{
- int ret;
- u_char *error;
- size_t erroff;
- njs_uint_t options;
- u_char errstr[128];
-
- options = PCRE2_ALT_BSUX | PCRE2_MATCH_UNSET_BACKREF;
-
- if ((flags & NJS_REGEX_IGNORE_CASE)) {
- options |= PCRE2_CASELESS;
- }
-
- if ((flags & NJS_REGEX_MULTILINE)) {
- options |= PCRE2_MULTILINE;
- }
-
- if ((flags & NJS_REGEX_STICKY)) {
- options |= PCRE2_ANCHORED;
- }
-
- if ((flags & NJS_REGEX_UTF8)) {
- options |= PCRE2_UTF;
- }
-
- regex->code = pcre2_compile(source, len, options, &ret, &erroff, ctx);
-
- if (njs_slow_path(regex->code == NULL)) {
- error = &source[erroff];
-
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre_compile2(\"%s\") failed: %s at \"%s\"",
- source, njs_regex_pcre2_error(ret, errstr), error);
-
- return NJS_DECLINED;
- }
-
- ret = pcre2_pattern_info(regex->code, PCRE2_INFO_CAPTURECOUNT,
- ®ex->ncaptures);
-
- if (njs_slow_path(ret < 0)) {
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre2_pattern_info(\"%s\", PCRE2_INFO_CAPTURECOUNT) failed: %s",
- source, njs_regex_pcre2_error(ret, errstr));
-
- return NJS_ERROR;
- }
-
- ret = pcre2_pattern_info(regex->code, PCRE2_INFO_BACKREFMAX,
- ®ex->backrefmax);
-
- if (njs_slow_path(ret < 0)) {
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre2_pattern_info(\"%s\", PCRE2_INFO_BACKREFMAX) failed: %s",
- source, njs_regex_pcre2_error(ret, errstr));
-
- return NJS_ERROR;
- }
-
- /* Reserve additional elements for the first "$0" capture. */
- regex->ncaptures++;
-
- if (regex->ncaptures > 1) {
- ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMECOUNT,
- ®ex->nentries);
-
- if (njs_slow_path(ret < 0)) {
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMECOUNT) failed: %s",
- source, njs_regex_pcre2_error(ret, errstr));
-
- return NJS_ERROR;
- }
-
- if (regex->nentries != 0) {
- ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMEENTRYSIZE,
- ®ex->entry_size);
-
- if (njs_slow_path(ret < 0)) {
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMEENTRYSIZE)"
- " failed: %s", source,
- njs_regex_pcre2_error(ret, errstr));
-
- return NJS_ERROR;
- }
-
- ret = pcre2_pattern_info(regex->code, PCRE2_INFO_NAMETABLE,
- ®ex->entries);
-
- if (njs_slow_path(ret < 0)) {
- njs_alert(trace, NJS_LEVEL_ERROR,
- "pcre2_pattern_info(\"%s\", PCRE2_INFO_NAMETABLE) "
- "failed: %s", source,
- njs_regex_pcre2_error(ret, errstr));
-
- return NJS_ERROR;
- }
- }
- }
-
- return NJS_OK;
-}
-
-
-njs_bool_t
-njs_regex_is_valid(njs_regex_t *regex)
-{
- return (regex->code != NULL);
-}
-
-
-njs_int_t
-njs_regex_named_captures(njs_regex_t *regex, njs_str_t *name, int n)
-{
- char *entry;
-
- if (name == NULL) {
- return regex->nentries;
- }
-
- if (n >= regex->nentries) {
- return NJS_ERROR;
- }
-
- entry = regex->entries + regex->entry_size * n;
-
- name->start = (u_char *) entry + 2;
- name->length = njs_strlen(name->start);
-
- return (entry[0] << 8) + entry[1];
-}
-
-
-njs_regex_match_data_t *
-njs_regex_match_data(njs_regex_t *regex, njs_regex_generic_ctx_t *ctx)
-{
- if (regex != NULL) {
- return pcre2_match_data_create_from_pattern(regex->code, ctx);
- }
-
- return pcre2_match_data_create(0, ctx);
-}
-
-
-void
-njs_regex_match_data_free(njs_regex_match_data_t *match_data,
- njs_regex_generic_ctx_t *unused)
-{
- pcre2_match_data_free(match_data);
-}
-
-
-njs_int_t
-njs_regex_match(njs_regex_t *regex, const u_char *subject, size_t off,
- size_t len, njs_regex_match_data_t *match_data, njs_trace_t *trace)
-{
- int ret;
- u_char errstr[128];
-
- ret = pcre2_match(regex->code, subject, len, off, 0, match_data, NULL);
-
- if (ret < 0) {
- if (ret == PCRE2_ERROR_NOMATCH) {
- return NJS_DECLINED;
- }
-
- njs_alert(trace, NJS_LEVEL_ERROR, "pcre2_match() failed: %s",
- njs_regex_pcre2_error(ret, errstr));
- return NJS_ERROR;
- }
-
- return ret;
-}
-
-
-size_t
-njs_regex_capture(njs_regex_match_data_t *match_data, njs_uint_t n)
-{
- size_t c;
-
- c = pcre2_get_ovector_pointer(match_data)[n];
-
- if (c == PCRE2_UNSET) {
- return NJS_REGEX_UNSET;
- }
-
- return c;
-}
-
-
-static const u_char *
-njs_regex_pcre2_error(int errcode, u_char buffer[128])
-{
- pcre2_get_error_message(errcode, buffer, 128);
-
- return buffer;
-}