8
9
#include <ngx_core.h>
11
17
static void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
12
18
static void ngx_libc_cdecl ngx_regex_free(void *p);
19
#if (NGX_HAVE_PCRE_JIT)
20
static void ngx_pcre_free_studies(void *data);
23
static ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
25
static void *ngx_regex_create_conf(ngx_cycle_t *cycle);
26
static char *ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf);
28
static char *ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data);
29
static ngx_conf_post_t ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
32
static ngx_command_t ngx_regex_commands[] = {
34
{ ngx_string("pcre_jit"),
35
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
36
ngx_conf_set_flag_slot,
38
offsetof(ngx_regex_conf_t, pcre_jit),
39
&ngx_regex_pcre_jit_post },
45
static ngx_core_module_t ngx_regex_module_ctx = {
47
ngx_regex_create_conf,
52
ngx_module_t ngx_regex_module = {
54
&ngx_regex_module_ctx, /* module context */
55
ngx_regex_commands, /* module directives */
56
NGX_CORE_MODULE, /* module type */
57
NULL, /* init master */
58
ngx_regex_module_init, /* init module */
59
NULL, /* init process */
60
NULL, /* init thread */
61
NULL, /* exit thread */
62
NULL, /* exit process */
63
NULL, /* exit master */
15
68
static ngx_pool_t *ngx_pcre_pool;
69
static ngx_list_t *ngx_pcre_studies;
27
ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
80
static ngx_inline void
81
ngx_regex_malloc_init(ngx_pool_t *pool)
34
84
ngx_core_tls_t *tls;
36
#if (NGX_SUPPRESS_WARN)
40
86
if (ngx_threaded) {
41
87
tls = ngx_thread_get_tls(ngx_core_tls_key);
49
94
ngx_pcre_pool = pool;
98
static ngx_inline void
99
ngx_regex_malloc_done(void)
105
tls = ngx_thread_get_tls(ngx_core_tls_key);
53
re = pcre_compile((const char *) pattern->data, (int) options,
112
ngx_pcre_pool = NULL;
117
ngx_regex_compile(ngx_regex_compile_t *rc)
123
ngx_regex_elt_t *elt;
125
ngx_regex_malloc_init(rc->pool);
127
re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
54
128
&errstr, &erroff, NULL);
130
/* ensure that there is no current pool */
131
ngx_regex_malloc_done();
57
if ((size_t) erroff == pattern->len) {
58
ngx_snprintf(err->data, err->len - 1,
59
"pcre_compile() failed: %s in \"%s\"%Z",
60
errstr, pattern->data);
134
if ((size_t) erroff == rc->pattern.len) {
135
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
136
"pcre_compile() failed: %s in \"%V\"",
137
errstr, &rc->pattern)
62
ngx_snprintf(err->data, err->len - 1,
63
"pcre_compile() failed: %s in \"%s\" at \"%s\"%Z",
64
errstr, pattern->data, pattern->data + erroff);
68
/* ensure that there is no current pool */
85
ngx_regex_capture_count(ngx_regex_t *re)
91
rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n);
94
return (ngx_int_t) rc;
102
ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size)
106
rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0,
110
return NGX_REGEX_NO_MATCHED;
141
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
142
"pcre_compile() failed: %s in \"%V\" at \"%s\"",
143
errstr, &rc->pattern, rc->pattern.data + erroff)
150
rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
151
if (rc->regex == NULL) {
155
rc->regex->code = re;
157
/* do not study at runtime */
159
if (ngx_pcre_studies != NULL) {
160
elt = ngx_list_push(ngx_pcre_studies);
165
elt->regex = rc->regex;
166
elt->name = rc->pattern.data;
169
n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
171
p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
175
if (rc->captures == 0) {
179
n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
181
p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
185
if (rc->named_captures == 0) {
189
n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
191
p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
195
n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
197
p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
205
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
280
#if (NGX_HAVE_PCRE_JIT)
283
ngx_pcre_free_studies(void *data)
285
ngx_list_t *studies = data;
288
ngx_list_part_t *part;
289
ngx_regex_elt_t *elts;
291
part = &studies->part;
294
for (i = 0 ; /* void */ ; i++) {
296
if (i >= part->nelts) {
297
if (part->next == NULL) {
306
if (elts[i].regex->extra != NULL) {
307
pcre_free_study(elts[i].regex->extra);
316
ngx_regex_module_init(ngx_cycle_t *cycle)
321
ngx_list_part_t *part;
322
ngx_regex_elt_t *elts;
326
#if (NGX_HAVE_PCRE_JIT)
328
ngx_regex_conf_t *rcf;
329
ngx_pool_cleanup_t *cln;
331
rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
334
opt = PCRE_STUDY_JIT_COMPILE;
337
* The PCRE JIT compiler uses mmap for its executable codes, so we
338
* have to explicitly call the pcre_free_study() function to free
342
cln = ngx_pool_cleanup_add(cycle->pool, 0);
347
cln->handler = ngx_pcre_free_studies;
348
cln->data = ngx_pcre_studies;
353
ngx_regex_malloc_init(cycle->pool);
355
part = &ngx_pcre_studies->part;
358
for (i = 0 ; /* void */ ; i++) {
360
if (i >= part->nelts) {
361
if (part->next == NULL) {
370
elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
372
if (errstr != NULL) {
373
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
374
"pcre_study() failed: %s in \"%s\"",
375
errstr, elts[i].name);
378
#if (NGX_HAVE_PCRE_JIT)
379
if (opt & PCRE_STUDY_JIT_COMPILE) {
383
n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra,
384
PCRE_INFO_JIT, &jit);
386
if (n != 0 || jit != 1) {
387
ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
388
"JIT compiler does not support pattern: \"%s\"",
395
ngx_regex_malloc_done();
397
ngx_pcre_studies = NULL;
404
ngx_regex_create_conf(ngx_cycle_t *cycle)
406
ngx_regex_conf_t *rcf;
408
rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
413
rcf->pcre_jit = NGX_CONF_UNSET;
415
ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
416
if (ngx_pcre_studies == NULL) {
425
ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
427
ngx_regex_conf_t *rcf = conf;
429
ngx_conf_init_value(rcf->pcre_jit, 0);
436
ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
438
ngx_flag_t *fp = data;
444
#if (NGX_HAVE_PCRE_JIT)
449
r = pcre_config(PCRE_CONFIG_JIT, &jit);
451
if (r != 0 || jit != 1) {
452
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
453
"PCRE library does not support JIT");
458
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
459
"nginx was built without PCRE JIT support");