89
100
static void ngx_http_lua_ngx_re_gmatch_cleanup(void *data);
90
101
static int ngx_http_lua_ngx_re_gmatch_gc(lua_State *L);
91
102
static void ngx_http_lua_re_collect_named_captures(lua_State *L,
92
u_char *name_table, int name_count, int name_entry_size,
103
int res_tb_idx, u_char *name_table, int name_count, int name_entry_size,
93
104
unsigned flags, ngx_str_t *subj);
96
#define ngx_http_lua_regex_exec(re, e, s, start, captures, size) \
97
pcre_exec(re, e, (const char *) (s)->data, (s)->len, start, 0, \
107
#define ngx_http_lua_regex_exec(re, e, s, start, captures, size, opts) \
108
pcre_exec(re, e, (const char *) (s)->data, (s)->len, start, opts, \
101
112
#define ngx_http_lua_regex_dfa_exec(re, e, s, start, captures, size, ws, \
103
pcre_dfa_exec(re, e, (const char *) (s)->data, (s)->len, start, 0, \
114
pcre_dfa_exec(re, e, (const char *) (s)->data, (s)->len, start, opts, \
104
115
captures, size, ws, wscount)
108
119
ngx_http_lua_ngx_re_match(lua_State *L)
121
return ngx_http_lua_ngx_re_match_helper(L, 1 /* want captures */);
126
ngx_http_lua_ngx_re_find(lua_State *L)
128
return ngx_http_lua_ngx_re_match_helper(L, 0 /* want captures */);
133
ngx_http_lua_ngx_re_match_helper(lua_State *L, int wantcaps)
111
137
ngx_http_request_t *r;
487
547
dd("rc = %d", (int) rc);
489
lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);
491
for (i = 0, n = 0; i < rc; i++, n += 2) {
492
dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
497
lua_pushlstring(L, (char *) &subj.data[cap[n]],
498
cap[n + 1] - cap[n]);
500
dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
503
lua_rawseti(L, -2, (int) i);
506
if (name_count > 0) {
507
ngx_http_lua_re_collect_named_captures(L, name_table, name_count,
508
name_entry_size, flags, &subj);
511
549
if (nargs == 4) { /* having ctx table */
513
lua_pushinteger(L, (lua_Integer) pos);
551
lua_pushinteger(L, (lua_Integer) (pos + 1));
514
552
lua_setfield(L, 4, "pos");
556
if (group_id > re_comp.captures) {
559
lua_pushliteral(L, "nth out of bound");
563
if (group_id >= rc) {
572
from = cap[group_id * 2] + 1;
573
to = cap[group_id * 2 + 1];
574
if (from < 0 || to < 0) {
580
lua_pushinteger(L, from);
581
lua_pushinteger(L, to);
586
if (res_tb_idx == 0) {
587
lua_createtable(L, rc /* narr */, 0 /* nrec */);
588
res_tb_idx = lua_gettop(L);
591
for (i = 0, n = 0; i < rc; i++, n += 2) {
592
dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
597
lua_pushlstring(L, (char *) &subj.data[cap[n]],
598
cap[n + 1] - cap[n]);
600
dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
603
lua_rawseti(L, res_tb_idx, (int) i);
606
if (name_count > 0) {
607
ngx_http_lua_re_collect_named_captures(L, res_tb_idx, name_table,
608
name_count, name_entry_size,
517
612
if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
2092
#ifndef NGX_HTTP_LUA_NO_FFI_API
2093
ngx_http_lua_regex_t *
2094
ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
2095
int flags, int pcre_opts, u_char *errstr,
2098
int *cap = NULL, ovecsize;
2102
ngx_pool_t *pool, *old_pool;
2103
pcre_extra *sd = NULL;
2104
ngx_http_lua_regex_t *re;
2106
ngx_http_lua_main_conf_t *lmcf;
2107
ngx_http_lua_regex_compile_t re_comp;
2109
pool = ngx_create_pool(512, ngx_cycle->log);
2115
re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
2117
ngx_destroy_pool(pool);
2125
re_comp.options = pcre_opts;
2126
re_comp.pattern.data = (u_char *) pat;
2127
re_comp.pattern.len = pat_len;
2128
re_comp.err.len = errstr_size;
2129
re_comp.err.data = errstr;
2130
re_comp.pool = pool;
2132
old_pool = ngx_http_lua_pcre_malloc_init(pool);
2133
rc = ngx_http_lua_regex_compile(&re_comp);
2134
ngx_http_lua_pcre_malloc_done(old_pool);
2137
re_comp.err.data[re_comp.err.len] = '\0';
2138
msg = (char *) re_comp.err.data;
2142
#if (LUA_HAVE_PCRE_JIT)
2144
if (flags & NGX_LUA_RE_MODE_JIT) {
2146
old_pool = ngx_http_lua_pcre_malloc_init(pool);
2147
sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);
2148
ngx_http_lua_pcre_malloc_done(old_pool);
2152
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
2153
"pcre study failed with PCRE_STUDY_JIT_COMPILE: "
2154
"%s (%p)", msg, sd);
2160
old_pool = ngx_http_lua_pcre_malloc_init(pool);
2162
pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);
2164
ngx_http_lua_pcre_malloc_done(old_pool);
2166
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
2167
"pcre JIT compiling result: %d", jitted);
2169
# endif /* !(NGX_DEBUG) */
2172
old_pool = ngx_http_lua_pcre_malloc_init(pool);
2173
sd = pcre_study(re_comp.regex, 0, &msg);
2174
ngx_http_lua_pcre_malloc_done(old_pool);
2177
#endif /* LUA_HAVE_PCRE_JIT */
2179
lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
2180
ngx_http_lua_module);
2182
if (sd && lmcf && lmcf->regex_match_limit > 0) {
2183
sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
2184
sd->match_limit = lmcf->regex_match_limit;
2187
if (flags & NGX_LUA_RE_MODE_DFA) {
2191
ovecsize = (re_comp.captures + 1) * 3;
2194
dd("allocating cap with size: %d", (int) ovecsize);
2196
cap = ngx_palloc(pool, ovecsize * sizeof(int));
2202
if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMECOUNT,
2203
&re->name_count) != 0)
2205
msg = "cannot acquire named subpattern count";
2209
if (re->name_count > 0) {
2210
if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMEENTRYSIZE,
2211
&re->name_entry_size) != 0)
2213
msg = "cannot acquire named subpattern entry size";
2217
if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMETABLE,
2218
&re->name_table) != 0)
2220
msg = "cannot acquire named subpattern table";
2225
re->regex = re_comp.regex;
2227
re->ncaptures = re_comp.captures;
2234
p = ngx_snprintf(errstr, errstr_size - 1, "%s", msg);
2238
ngx_http_lua_regex_free_study_data(pool, sd);
2242
ngx_destroy_pool(pool);
2250
ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
2251
const u_char *s, size_t len, int pos)
2253
int rc, ovecsize, exec_opts, *cap;
2260
if (flags & NGX_LUA_RE_MODE_DFA) {
2264
ovecsize = (re->ncaptures + 1) * 3;
2267
if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
2268
exec_opts = PCRE_NO_UTF8_CHECK;
2274
subj.data = (u_char *) s;
2277
if (flags & NGX_LUA_RE_MODE_DFA) {
2279
#if LUA_HAVE_PCRE_DFA
2281
int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
2282
rc = ngx_http_lua_regex_dfa_exec(re->regex, sd, &subj,
2283
(int) pos, cap, ovecsize, ws,
2284
sizeof(ws)/sizeof(ws[0]), exec_opts);
2286
#else /* LUA_HAVE_PCRE_DFA */
2288
return PCRE_ERROR_INTERNAL;
2290
#endif /* LUA_HAVE_PCRE_DFA */
2293
rc = ngx_http_lua_regex_exec(re->regex, sd, &subj, (int) pos, cap,
2294
ovecsize, exec_opts);
2302
ngx_http_lua_ffi_destroy_regex(ngx_http_lua_regex_t *re)
2304
dd("destroy regex called");
2306
if (re == NULL || re->pool == NULL) {
2311
#if LUA_HAVE_PCRE_JIT
2312
pcre_free_study(re->regex_sd);
2314
pcre_free(re->regex_sd);
2318
ngx_destroy_pool(re->pool);
2323
ngx_http_lua_ffi_compile_replace_template(ngx_http_lua_regex_t *re,
2324
const u_char *replace_data, size_t replace_len)
2328
ngx_http_lua_complex_value_t *ctpl;
2329
ngx_http_lua_compile_complex_value_t ccv;
2331
ctpl = ngx_palloc(re->pool, sizeof(ngx_http_lua_complex_value_t));
2336
if (replace_len != 0) {
2337
/* copy the string buffer pointed to by tpl.data from Lua VM */
2338
tpl.data = ngx_palloc(re->pool, replace_len + 1);
2339
if (tpl.data == NULL) {
2343
ngx_memcpy(tpl.data, replace_data, replace_len);
2344
tpl.data[replace_len] = '\0';
2347
tpl.data = (u_char *) replace_data;
2350
tpl.len = replace_len;
2352
ngx_memzero(&ccv, sizeof(ngx_http_lua_compile_complex_value_t));
2353
ccv.pool = re->pool;
2354
ccv.log = ngx_cycle->log;
2356
ccv.complex_value = ctpl;
2358
rc = ngx_http_lua_compile_complex_value(&ccv);
2366
ngx_http_lua_script_engine_t *
2367
ngx_http_lua_ffi_create_script_engine(void)
2369
return ngx_calloc(sizeof(ngx_http_lua_script_engine_t), ngx_cycle->log);
2374
ngx_http_lua_ffi_init_script_engine(ngx_http_lua_script_engine_t *e,
2375
const unsigned char *subj, ngx_http_lua_regex_t *compiled, int count)
2377
e->log = ngx_cycle->log;
2378
e->ncaptures = count * 2;
2379
e->captures = compiled->captures;
2380
e->captures_data = (u_char *) subj;
2385
ngx_http_lua_ffi_destroy_script_engine(ngx_http_lua_script_engine_t *e)
2392
ngx_http_lua_ffi_script_eval_len(ngx_http_lua_script_engine_t *e,
2393
ngx_http_lua_complex_value_t *val)
2397
ngx_http_lua_script_len_code_pt lcode;
2399
e->ip = val->lengths;
2402
while (*(uintptr_t *) e->ip) {
2403
lcode = *(ngx_http_lua_script_len_code_pt *) e->ip;
2412
ngx_http_lua_ffi_script_eval_data(ngx_http_lua_script_engine_t *e,
2413
ngx_http_lua_complex_value_t *val, u_char *dst, size_t len)
2415
ngx_http_lua_script_code_pt code;
2417
e->ip = val->values;
2420
while (*(uintptr_t *) e->ip) {
2421
code = *(ngx_http_lua_script_code_pt *) e->ip;
2428
ngx_http_lua_ffi_max_regex_cache_size(void)
2430
ngx_http_lua_main_conf_t *lmcf;
2431
lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
2432
ngx_http_lua_module);
2436
return (uint32_t) lmcf->regex_cache_max_entries;
2438
#endif /* NGX_HTTP_LUA_NO_FFI_API */
1975
2441
#endif /* NGX_PCRE */
1977
2443
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */