diff options
author | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2025-03-01 12:42:23 +0800 |
commit | 3f33461e4948bf05e60bdff35ec6c57a649c7860 (patch) | |
tree | 284c2ba95a41536ae1bff6bea710db0709a64739 /ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c | |
download | openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.tar.gz openresty-3f33461e4948bf05e60bdff35ec6c57a649c7860.zip |
openresty bundle
Diffstat (limited to 'ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c')
-rw-r--r-- | ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c | 1007 |
1 files changed, 1007 insertions, 0 deletions
diff --git a/ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c new file mode 100644 index 0000000..080e5dd --- /dev/null +++ b/ngx_stream_lua-0.0.16/src/ngx_stream_lua_regex.c @@ -0,0 +1,1007 @@ + +/* + * !!! DO NOT EDIT DIRECTLY !!! + * This file was automatically generated from the following template: + * + * src/subsys/ngx_subsys_lua_regex.c.tt2 + */ + + +/* + * Copyright (C) Yichun Zhang (agentzh) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + + +#if (NGX_PCRE) + +#include "ngx_stream_lua_pcrefix.h" +#include "ngx_stream_lua_script.h" +#include "ngx_stream_lua_util.h" + + +#if (PCRE_MAJOR >= 6 || NGX_PCRE2) +# define LUA_HAVE_PCRE_DFA 1 +#else +# define LUA_HAVE_PCRE_DFA 0 +#endif + + +#if (NGX_PCRE2) +static pcre2_compile_context *ngx_regex_compile_context; +static pcre2_match_context *ngx_regex_match_context; +static pcre2_match_data *ngx_regex_match_data; +static ngx_uint_t ngx_regex_match_data_size = 0; + +#define PCRE2_VERSION_SIZE 64 +static char ngx_pcre2_version[PCRE2_VERSION_SIZE]; +#endif + + +#define NGX_LUA_RE_MODE_DFA (1<<1) +#define NGX_LUA_RE_MODE_JIT (1<<2) +#define NGX_LUA_RE_NO_UTF8_CHECK (1<<4) + +#define NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT (100) + +#define NGX_LUA_RE_MIN_JIT_STACK_SIZE 32 * 1024 + + +typedef struct { + ngx_pool_t *pool; + u_char *name_table; + int name_count; + int name_entry_size; + + int ncaptures; + int *captures; + +#if (NGX_PCRE2) + pcre2_code *regex; + /* + * pcre2 doesn't use pcre_extra any more, + * just for keeping same memory layout in the lua ffi cdef + */ + void *regex_sd; +#else + pcre *regex; + pcre_extra *regex_sd; +#endif + + ngx_stream_lua_complex_value_t *replace; + + /* only for (stap) debugging, and may be an invalid pointer */ + const u_char *pattern; +} ngx_stream_lua_regex_t; + + +typedef struct { + ngx_str_t pattern; + ngx_pool_t *pool; + ngx_int_t options; + +#if (NGX_PCRE2) + pcre2_code *regex; +#else + pcre *regex; +#endif + int captures; + ngx_str_t err; +} ngx_stream_lua_regex_compile_t; + + +typedef struct { + ngx_stream_lua_request_t *request; + +#if (NGX_PCRE2) + pcre2_code *regex; +#else + pcre *regex; + pcre_extra *regex_sd; +#endif + int ncaptures; + int *captures; + int captures_len; + uint8_t flags; +} ngx_stream_lua_regex_ctx_t; + + +static ngx_int_t ngx_stream_lua_regex_compile( + ngx_stream_lua_regex_compile_t *rc); + + +#define ngx_stream_lua_regex_exec(re, e, s, start, captures, size, \ + opts) \ + pcre_exec(re, e, (const char *) (s)->data, (s)->len, start, opts, \ + captures, size) + + +#define ngx_stream_lua_regex_dfa_exec(re, e, s, start, captures, size, \ + ws, wscount, opts) \ + pcre_dfa_exec(re, e, (const char *) (s)->data, (s)->len, start, opts, \ + captures, size, ws, wscount) + + +static void +ngx_stream_lua_regex_free_study_data(ngx_pool_t *pool, + ngx_stream_lua_regex_t *re) +{ + ngx_pool_t *old_pool; + +#if (NGX_PCRE2) + if (re && re->regex) { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + + pcre2_code_free(re->regex); + + ngx_stream_lua_pcre_malloc_done(old_pool); + + re->regex = NULL; + } +#else + if (re && re->regex_sd) { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); +#if LUA_HAVE_PCRE_JIT + pcre_free_study(re->regex_sd); +#else + pcre_free(re->regex_sd); +#endif + ngx_stream_lua_pcre_malloc_done(old_pool); + + re->regex_sd = NULL; + } +#endif +} + + +#if (NGX_PCRE2) +static ngx_int_t +ngx_stream_lua_regex_compile(ngx_stream_lua_regex_compile_t *rc) +{ + int n, errcode; + char *p; + size_t erroff; + u_char errstr[128]; + pcre2_code *re; + ngx_pool_t *old_pool; + pcre2_general_context *gctx; + pcre2_compile_context *cctx; + + ngx_stream_lua_main_conf_t *lmcf; + + if (ngx_regex_compile_context == NULL) { + /* + * Allocate a compile context if not yet allocated. This uses + * direct allocations from heap, so the result can be cached + * even at runtime. + */ + + old_pool = ngx_stream_lua_pcre_malloc_init(NULL); + + gctx = pcre2_general_context_create(ngx_stream_lua_pcre_malloc, + ngx_stream_lua_pcre_free, + NULL); + if (gctx == NULL) { + ngx_stream_lua_pcre_malloc_done(old_pool); + goto nomem; + } + + cctx = pcre2_compile_context_create(gctx); + if (cctx == NULL) { + pcre2_general_context_free(gctx); + ngx_stream_lua_pcre_malloc_done(old_pool); + goto nomem; + } + + ngx_regex_compile_context = cctx; + + ngx_regex_match_context = pcre2_match_context_create(gctx); + if (ngx_regex_match_context == NULL) { + pcre2_general_context_free(gctx); + ngx_stream_lua_pcre_malloc_done(old_pool); + goto nomem; + } + + lmcf = ngx_stream_cycle_get_module_main_conf(ngx_cycle, + ngx_stream_lua_module); + if (lmcf && lmcf->regex_match_limit > 0) { + pcre2_set_match_limit(ngx_regex_match_context, + lmcf->regex_match_limit); + } + + pcre2_general_context_free(gctx); + ngx_stream_lua_pcre_malloc_done(old_pool); + } + + old_pool = ngx_stream_lua_pcre_malloc_init(rc->pool); + + re = pcre2_compile(rc->pattern.data, + rc->pattern.len, rc->options, + &errcode, &erroff, ngx_regex_compile_context); + + ngx_stream_lua_pcre_malloc_done(old_pool); + + if (re == NULL) { + pcre2_get_error_message(errcode, errstr, 128); + + if ((size_t) erroff == rc->pattern.len) { + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre2_compile() failed: %s in \"%V\"", + errstr, &rc->pattern) + - rc->err.data; + + } else { + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre2_compile() failed: %s in " + "\"%V\" at \"%s\"", errstr, &rc->pattern, + rc->pattern.data + erroff) + - rc->err.data; + } + + return NGX_ERROR; + } + + rc->regex = re; + + n = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &rc->captures); + if (n < 0) { + p = "pcre2_pattern_info(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; + goto failed; + } + +#if (NGX_DEBUG) + ngx_log_debug3(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre2_compile: pattern[%V], options 0x%08Xd, ncaptures %d", + &rc->pattern, rc->options, rc->captures); +#endif + + return NGX_OK; + +failed: + + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) + - rc->err.data; + return NGX_ERROR; + +nomem: + + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "regex \"%V\" compilation failed: no memory", + &rc->pattern) + - rc->err.data; + return NGX_ERROR; +} + +#else + +static ngx_int_t +ngx_stream_lua_regex_compile(ngx_stream_lua_regex_compile_t *rc) +{ + int n, erroff; + char *p; + const char *errstr; + pcre *re; + ngx_pool_t *old_pool; + + old_pool = ngx_stream_lua_pcre_malloc_init(rc->pool); + + re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, + &errstr, &erroff, NULL); + + ngx_stream_lua_pcre_malloc_done(old_pool); + + if (re == NULL) { + if ((size_t) erroff == rc->pattern.len) { + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre_compile() failed: %s in \"%V\"", + errstr, &rc->pattern) + - rc->err.data; + + } else { + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, + "pcre_compile() failed: %s in \"%V\" " + "at \"%s\"", errstr, &rc->pattern, + rc->pattern.data + erroff) + - rc->err.data; + } + + return NGX_ERROR; + } + + rc->regex = re; + +#if 1 + n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); + if (n < 0) { + p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; + goto failed; + } +#endif + + return NGX_OK; + +failed: + + rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) + - rc->err.data; + return NGX_OK; +} +#endif + + +ngx_int_t +ngx_stream_lua_ffi_set_jit_stack_size(int size, u_char *errstr, + size_t *errstr_size) +{ +#if (LUA_HAVE_PCRE_JIT) + + ngx_stream_lua_main_conf_t *lmcf; + ngx_pool_t *pool, *old_pool; + + lmcf = ngx_stream_cycle_get_module_main_conf(ngx_cycle, + ngx_stream_lua_module); + + if (size < NGX_LUA_RE_MIN_JIT_STACK_SIZE) { + size = NGX_LUA_RE_MIN_JIT_STACK_SIZE; + } + + pool = lmcf->pool; + + dd("server pool %p", lmcf->pool); + + if (lmcf->jit_stack) { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + +#if (NGX_PCRE2) + pcre2_jit_stack_free(lmcf->jit_stack); +#else + pcre_jit_stack_free(lmcf->jit_stack); +#endif + + ngx_stream_lua_pcre_malloc_done(old_pool); + } + + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + +#if (NGX_PCRE2) + lmcf->jit_stack = pcre2_jit_stack_create(NGX_LUA_RE_MIN_JIT_STACK_SIZE, + size, NULL); +#else + lmcf->jit_stack = pcre_jit_stack_alloc(NGX_LUA_RE_MIN_JIT_STACK_SIZE, + size); +#endif + + ngx_stream_lua_pcre_malloc_done(old_pool); + + if (lmcf->jit_stack == NULL) { + *errstr_size = ngx_snprintf(errstr, *errstr_size, + "pcre jit stack allocation failed") + - errstr; + return NGX_ERROR; + } + + return NGX_OK; + +#else /* LUA_HAVE_PCRE_JIT */ + + *errstr_size = ngx_snprintf(errstr, *errstr_size, + "no pcre jit support found") - errstr; + return NGX_ERROR; + +#endif +} + + +#if (NGX_PCRE2) +static void +ngx_stream_lua_regex_jit_compile(ngx_stream_lua_regex_t *re, int flags, + ngx_pool_t *pool, ngx_stream_lua_main_conf_t *lmcf, + ngx_stream_lua_regex_compile_t *re_comp) +{ + ngx_int_t ret; + ngx_pool_t *old_pool; + + if (flags & NGX_LUA_RE_MODE_JIT) { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + ret = pcre2_jit_compile(re_comp->regex, PCRE2_JIT_COMPLETE); + + if (ret != 0) { + ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, + "pcre2_jit_compile() failed: %d in \"%V\", " + "ignored", + ret, &re_comp->pattern); + +#if (NGX_DEBUG) + + } else { + ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre2 JIT compiled successfully"); +# endif /* !(NGX_DEBUG) */ + } + + ngx_stream_lua_pcre_malloc_done(old_pool); + + } + + if (lmcf && lmcf->jit_stack) { + pcre2_jit_stack_assign(ngx_regex_match_context, NULL, + lmcf->jit_stack); + } + + return; +} + +#else + +static void +ngx_stream_lua_regex_jit_compile(ngx_stream_lua_regex_t *re, int flags, + ngx_pool_t *pool, ngx_stream_lua_main_conf_t *lmcf, + ngx_stream_lua_regex_compile_t *re_comp) +{ + const char *msg; + pcre_extra *sd = NULL; + ngx_pool_t *old_pool; + + +#if (LUA_HAVE_PCRE_JIT) + if (flags & NGX_LUA_RE_MODE_JIT) { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + sd = pcre_study(re_comp->regex, PCRE_STUDY_JIT_COMPILE, &msg); + ngx_stream_lua_pcre_malloc_done(old_pool); + +# if (NGX_DEBUG) + if (msg != NULL) { + ngx_log_debug2(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre study failed with PCRE_STUDY_JIT_COMPILE: " + "%s (%p)", msg, sd); + } + + if (sd != NULL) { + int jitted; + + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + + pcre_fullinfo(re_comp->regex, sd, PCRE_INFO_JIT, &jitted); + + ngx_stream_lua_pcre_malloc_done(old_pool); + + ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre JIT compiling result: %d", jitted); + } +# endif /* !(NGX_DEBUG) */ + + } else { + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + sd = pcre_study(re_comp->regex, 0, &msg); + ngx_stream_lua_pcre_malloc_done(old_pool); + } + + if (sd && lmcf && lmcf->jit_stack) { + pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack); + } + + if (sd + && lmcf && lmcf->regex_match_limit > 0 + && !(flags & NGX_LUA_RE_MODE_DFA)) + { + sd->flags |= PCRE_EXTRA_MATCH_LIMIT; + sd->match_limit = lmcf->regex_match_limit; + } + +#endif /* LUA_HAVE_PCRE_JIT */ + + re->regex_sd = sd; +} +#endif + + +#if (NGX_PCRE2) +void +ngx_stream_lua_regex_cleanup(void *data) +{ + ngx_pool_t *old_pool; + ngx_stream_lua_main_conf_t *lmcf; + + lmcf = data; + + if (ngx_regex_compile_context) { + old_pool = ngx_stream_lua_pcre_malloc_init(NULL); + pcre2_compile_context_free(ngx_regex_compile_context); + ngx_regex_compile_context = NULL; + ngx_stream_lua_pcre_malloc_done(old_pool); + } + + if (lmcf && lmcf->jit_stack) { + old_pool = ngx_stream_lua_pcre_malloc_init(NULL); + + pcre2_jit_stack_free(lmcf->jit_stack); + lmcf->jit_stack = NULL; + + ngx_stream_lua_pcre_malloc_done(old_pool); + } + + if (ngx_regex_match_data) { + old_pool = ngx_stream_lua_pcre_malloc_init(NULL); + pcre2_match_data_free(ngx_regex_match_data); + ngx_regex_match_data = NULL; + ngx_regex_match_data_size = 0; + ngx_stream_lua_pcre_malloc_done(old_pool); + } + +} +#endif + + +ngx_stream_lua_regex_t * +ngx_stream_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len, + int flags, int pcre_opts, u_char *errstr, + size_t errstr_size) +{ + int *cap = NULL, ovecsize; + u_char *p; + ngx_int_t rc; + const char *msg; + ngx_pool_t *pool, *old_pool; + ngx_stream_lua_regex_t *re = NULL; + ngx_stream_lua_main_conf_t *lmcf; + ngx_stream_lua_regex_compile_t re_comp; + + pool = ngx_create_pool(512, ngx_cycle->log); + if (pool == NULL) { + msg = "no memory"; + goto error; + } + + pool->log = (ngx_log_t *) &ngx_cycle->new_log; + + re = ngx_palloc(pool, sizeof(ngx_stream_lua_regex_t)); + if (re == NULL) { + ngx_destroy_pool(pool); + pool = NULL; + msg = "no memory"; + goto error; + } + + re->pool = pool; + re->regex = NULL; + re->regex_sd = NULL; + + re_comp.options = pcre_opts; + re_comp.pattern.data = (u_char *) pat; + re_comp.pattern.len = pat_len; + re_comp.err.len = errstr_size - 1; + re_comp.err.data = errstr; + re_comp.pool = pool; + + old_pool = ngx_stream_lua_pcre_malloc_init(pool); + rc = ngx_stream_lua_regex_compile(&re_comp); + ngx_stream_lua_pcre_malloc_done(old_pool); + + if (rc != NGX_OK) { + re_comp.err.data[re_comp.err.len] = '\0'; + msg = (char *) re_comp.err.data; + goto error; + } + + lmcf = ngx_stream_cycle_get_module_main_conf(ngx_cycle, + ngx_stream_lua_module); + + ngx_stream_lua_regex_jit_compile(re, flags, pool, lmcf, &re_comp); + + if (flags & NGX_LUA_RE_MODE_DFA) { + ovecsize = 2; + re_comp.captures = 0; + + } else { +#if (NGX_PCRE2) + ovecsize = (re_comp.captures + 1) * 2; +#else + ovecsize = (re_comp.captures + 1) * 3; +#endif + } + + dd("allocating cap with size: %d", (int) ovecsize); + + cap = ngx_palloc(pool, ovecsize * sizeof(int)); + if (cap == NULL) { + msg = "no memory"; + goto error; + } + +#if (NGX_PCRE2) + if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMECOUNT, + &re->name_count) < 0) + { + msg = "cannot acquire named subpattern count"; + goto error; + } + + if (re->name_count > 0) { + if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMEENTRYSIZE, + &re->name_entry_size) != 0) + { + msg = "cannot acquire named subpattern entry size"; + goto error; + } + + if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMETABLE, + &re->name_table) != 0) + { + msg = "cannot acquire named subpattern table"; + goto error; + } + } + +#else + if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMECOUNT, + &re->name_count) != 0) + { + msg = "cannot acquire named subpattern count"; + goto error; + } + + if (re->name_count > 0) { + if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMEENTRYSIZE, + &re->name_entry_size) != 0) + { + msg = "cannot acquire named subpattern entry size"; + goto error; + } + + if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMETABLE, + &re->name_table) != 0) + { + msg = "cannot acquire named subpattern table"; + goto error; + } + } +#endif + + re->regex = re_comp.regex; + re->ncaptures = re_comp.captures; + re->captures = cap; + re->replace = NULL; + + /* only for (stap) debugging, the pointer might be invalid when the + * string is collected later on.... */ + re->pattern = pat; + + return re; + +error: + + p = ngx_snprintf(errstr, errstr_size - 1, "%s", msg); + *p = '\0'; + + ngx_stream_lua_regex_free_study_data(pool, re); + + if (pool) { + ngx_destroy_pool(pool); + } + + return NULL; +} + + +#if (NGX_PCRE2) +int +ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags, + const u_char *s, size_t len, int pos) +{ + int rc, exec_opts = 0; + size_t *ov; + ngx_uint_t ovecpair, n, i; + ngx_pool_t *old_pool; + + if (flags & NGX_LUA_RE_MODE_DFA) { + ovecpair = 1; + re->ncaptures = 0; + + } else { + ovecpair = re->ncaptures + 1; + } + + old_pool = ngx_stream_lua_pcre_malloc_init(NULL); + + if (ngx_regex_match_data == NULL + || ovecpair > ngx_regex_match_data_size) + { + /* + * Allocate a match data if not yet allocated or smaller than + * needed. + */ + + if (ngx_regex_match_data) { + pcre2_match_data_free(ngx_regex_match_data); + } + + ngx_regex_match_data_size = ovecpair; + ngx_regex_match_data = pcre2_match_data_create(ovecpair, NULL); + + if (ngx_regex_match_data == NULL) { + rc = PCRE2_ERROR_NOMEMORY; + goto failed; + } + } + + if (flags & NGX_LUA_RE_NO_UTF8_CHECK) { + exec_opts = PCRE2_NO_UTF_CHECK; + + } else { + exec_opts = 0; + } + + if (flags & NGX_LUA_RE_MODE_DFA) { + int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT]; + rc = pcre2_dfa_match(re->regex, s, len, pos, exec_opts, + ngx_regex_match_data, ngx_regex_match_context, + ws, sizeof(ws) / sizeof(ws[0])); + + } else { + rc = pcre2_match(re->regex, s, len, pos, exec_opts, + ngx_regex_match_data, ngx_regex_match_context); + } + + if (rc < 0) { +#if (NGX_DEBUG) + ngx_log_debug4(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre2_match failed: flags 0x%05Xd, options 0x%08Xd, rc %d, " + "ovecpair %ui", flags, exec_opts, rc, ovecpair); +#endif + + goto failed; + } + + n = pcre2_get_ovector_count(ngx_regex_match_data); + ov = pcre2_get_ovector_pointer(ngx_regex_match_data); + +#if (NGX_DEBUG) + ngx_log_debug5(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0, + "pcre2_match: flags 0x%05Xd, options 0x%08Xd, rc %d, " + "n %ui, ovecpair %ui", flags, exec_opts, rc, n, ovecpair); +#endif + + if (n > ovecpair) { + n = ovecpair; + } + + for (i = 0; i < n; i++) { + re->captures[i * 2] = ov[i * 2]; + re->captures[i * 2 + 1] = ov[i * 2 + 1]; + } + +failed: + + ngx_stream_lua_pcre_malloc_done(old_pool); + + return rc; +} + +#else + +int +ngx_stream_lua_ffi_exec_regex(ngx_stream_lua_regex_t *re, int flags, + const u_char *s, size_t len, int pos) +{ + int rc, ovecsize, exec_opts, *cap; + ngx_str_t subj; + pcre_extra *sd; + + cap = re->captures; + sd = re->regex_sd; + + if (flags & NGX_LUA_RE_MODE_DFA) { + ovecsize = 2; + re->ncaptures = 0; + + } else { + /* How pcre_exec() returns captured substrings + * The first two-thirds of the vector is used to pass back captured + * substrings, each substring using a pair of integers. The remaining + * third of the vector is used as workspace by pcre_exec() while + * matching capturing subpatterns, and is not available for passing + * back information. The number passed in ovecsize should always be a + * multiple of three. If it is not, it is rounded down. + * + * When a match is successful, information about captured substrings is + * returned in pairs of integers, starting at the beginning of ovector, + * and continuing up to two-thirds of its length at the most. The first + * element of each pair is set to the byte offset of the first character + * in a substring, and the second is set to the byte offset of the first + * character after the end of a substring. + */ + ovecsize = (re->ncaptures + 1) * 3; + } + + if (flags & NGX_LUA_RE_NO_UTF8_CHECK) { + exec_opts = PCRE_NO_UTF8_CHECK; + + } else { + exec_opts = 0; + } + + subj.data = (u_char *) s; + subj.len = len; + + if (flags & NGX_LUA_RE_MODE_DFA) { + +#if LUA_HAVE_PCRE_DFA + + int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT]; + rc = ngx_stream_lua_regex_dfa_exec(re->regex, sd, &subj, + (int) pos, cap, ovecsize, ws, + sizeof(ws) / sizeof(ws[0]), exec_opts); + +#else + + return PCRE_ERROR_BADOPTION; + +#endif /* LUA_HAVE_PCRE_DFA */ + + } else { + rc = ngx_stream_lua_regex_exec(re->regex, sd, &subj, (int) pos, cap, + ovecsize, exec_opts); + } + + return rc; +} + +#endif + + +void +ngx_stream_lua_ffi_destroy_regex(ngx_stream_lua_regex_t *re) +{ + dd("destroy regex called"); + + if (re == NULL || re->pool == NULL) { + return; + } + + ngx_stream_lua_regex_free_study_data(re->pool, re); + + ngx_destroy_pool(re->pool); +} + + +int +ngx_stream_lua_ffi_compile_replace_template(ngx_stream_lua_regex_t *re, + const u_char *replace_data, size_t replace_len) +{ + ngx_int_t rc; + ngx_str_t tpl; + + ngx_stream_lua_complex_value_t *ctpl; + ngx_stream_lua_compile_complex_value_t ccv; + + ctpl = ngx_palloc(re->pool, sizeof(ngx_stream_lua_complex_value_t)); + if (ctpl == NULL) { + return NGX_ERROR; + } + + if (replace_len != 0) { + /* copy the string buffer pointed to by tpl.data from Lua VM */ + tpl.data = ngx_palloc(re->pool, replace_len + 1); + if (tpl.data == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(tpl.data, replace_data, replace_len); + tpl.data[replace_len] = '\0'; + + } else { + tpl.data = (u_char *) replace_data; + } + + tpl.len = replace_len; + + ngx_memzero(&ccv, sizeof(ngx_stream_lua_compile_complex_value_t)); + ccv.pool = re->pool; + ccv.log = ngx_cycle->log; + ccv.value = &tpl; + ccv.complex_value = ctpl; + + rc = ngx_stream_lua_compile_complex_value(&ccv); + + re->replace = ctpl; + + return rc; +} + + +ngx_stream_lua_script_engine_t * +ngx_stream_lua_ffi_create_script_engine(void) +{ + return ngx_calloc(sizeof(ngx_stream_lua_script_engine_t), ngx_cycle->log); +} + + +void +ngx_stream_lua_ffi_init_script_engine(ngx_stream_lua_script_engine_t *e, + const unsigned char *subj, ngx_stream_lua_regex_t *compiled, int count) +{ + e->log = ngx_cycle->log; + e->ncaptures = count * 2; + e->captures = compiled->captures; + e->captures_data = (u_char *) subj; +} + + +void +ngx_stream_lua_ffi_destroy_script_engine(ngx_stream_lua_script_engine_t *e) +{ + ngx_free(e); +} + + +size_t +ngx_stream_lua_ffi_script_eval_len(ngx_stream_lua_script_engine_t *e, + ngx_stream_lua_complex_value_t *val) +{ + size_t len; + + ngx_stream_lua_script_len_code_pt lcode; + + e->ip = val->lengths; + len = 0; + + while (*(uintptr_t *) e->ip) { + lcode = *(ngx_stream_lua_script_len_code_pt *) e->ip; + len += lcode(e); + } + + return len; +} + + +void +ngx_stream_lua_ffi_script_eval_data(ngx_stream_lua_script_engine_t *e, + ngx_stream_lua_complex_value_t *val, u_char *dst) +{ + ngx_stream_lua_script_code_pt code; + + e->ip = val->values; + e->pos = dst; + + while (*(uintptr_t *) e->ip) { + code = *(ngx_stream_lua_script_code_pt *) e->ip; + code(e); + } +} + + +uint32_t +ngx_stream_lua_ffi_max_regex_cache_size(void) +{ + ngx_stream_lua_main_conf_t *lmcf; + lmcf = ngx_stream_cycle_get_module_main_conf(ngx_cycle, + ngx_stream_lua_module); + if (lmcf == NULL) { + return 0; + } + return (uint32_t) lmcf->regex_cache_max_entries; +} + + +const char * +ngx_stream_lua_ffi_pcre_version(void) +{ +#if (NGX_PCRE2) + pcre2_config(PCRE2_CONFIG_VERSION, ngx_pcre2_version); + + return ngx_pcre2_version; +#else + return pcre_version(); +#endif +} + + +#endif /* NGX_PCRE */ + + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ |