~spuul/nginx/trunk

« back to all changes in this revision

Viewing changes to debian/modules/nginx-lua/src/ngx_http_lua_regex.c

  • Committer: Package Import Robot
  • Author(s): Christos Trochalakis, Christos Trochalakis
  • Date: 2014-02-13 11:41:49 UTC
  • mfrom: (1.3.32)
  • mto: This revision was merged to the branch mainline in revision 72.
  • Revision ID: package-import@ubuntu.com-20140213114149-tkp78c45rzu3wr6y
Tags: 1.4.5-1
[ Christos Trochalakis ]
* New upstream release.
* debian/modules/nginx-lua:
  + Update nginx-lua to v0.9.4
* debian/nginx-naxsi-ui.preinst:
  + Fix exit status issue (Closes: #735152)
* debian/control:
  + Fix arch:all to arch:any dependencies
  + Make nginx depend on specific flavor version
* debian/nginx-*.postinst:
  + Make nginx start by default (Closes: #735551)
* debian/nginx-*.prerm:
  + No need to check for invoke-rc.d,
    correctly set the exit code on error
* debian/nginx-common.nginx.init:
  + Rewrite some parts of the initscript
  + Introduce rotate command
  + Introduce upgrade command

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#define NGX_LUA_RE_MODE_DFA          (1<<1)
39
39
#define NGX_LUA_RE_MODE_JIT          (1<<2)
40
40
#define NGX_LUA_RE_MODE_DUPNAMES     (1<<3)
 
41
#define NGX_LUA_RE_NO_UTF8_CHECK     (1<<4)
41
42
 
42
43
#define NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT (100)
43
44
 
44
45
 
45
46
typedef struct {
 
47
#ifndef NGX_HTTP_LUA_NO_FFI_API
 
48
    ngx_pool_t                   *pool;
 
49
    u_char                       *name_table;
 
50
    int                           name_count;
 
51
    int                           name_entry_size;
 
52
#endif
 
53
 
 
54
    int                           ncaptures;
 
55
    int                          *captures;
 
56
 
46
57
    pcre                         *regex;
47
58
    pcre_extra                   *regex_sd;
48
 
    int                           ncaptures;
49
 
    int                          *captures;
50
59
 
51
60
    ngx_http_lua_complex_value_t    *replace;
52
61
} ngx_http_lua_regex_t;
79
88
static ngx_uint_t ngx_http_lua_ngx_re_parse_opts(lua_State *L,
80
89
    ngx_http_lua_regex_compile_t *re, ngx_str_t *opts, int narg);
81
90
static int ngx_http_lua_ngx_re_sub_helper(lua_State *L, unsigned global);
 
91
static int ngx_http_lua_ngx_re_match_helper(lua_State *L, int wantcaps);
 
92
static int ngx_http_lua_ngx_re_find(lua_State *L);
82
93
static int ngx_http_lua_ngx_re_match(lua_State *L);
83
94
static int ngx_http_lua_ngx_re_gmatch(lua_State *L);
84
95
static int ngx_http_lua_ngx_re_sub(lua_State *L);
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);
94
105
 
95
106
 
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,        \
98
109
              captures, size)
99
110
 
100
111
 
101
112
#define ngx_http_lua_regex_dfa_exec(re, e, s, start, captures, size, ws,     \
102
 
                                    wscount)                                 \
103
 
    pcre_dfa_exec(re, e, (const char *) (s)->data, (s)->len, start, 0,       \
 
113
                                    wscount, opts)                           \
 
114
    pcre_dfa_exec(re, e, (const char *) (s)->data, (s)->len, start, opts,    \
104
115
                  captures, size, ws, wscount)
105
116
 
106
117
 
107
118
static int
108
119
ngx_http_lua_ngx_re_match(lua_State *L)
109
120
{
 
121
    return ngx_http_lua_ngx_re_match_helper(L, 1 /* want captures */);
 
122
}
 
123
 
 
124
 
 
125
static int
 
126
ngx_http_lua_ngx_re_find(lua_State *L)
 
127
{
 
128
    return ngx_http_lua_ngx_re_match_helper(L, 0 /* want captures */);
 
129
}
 
130
 
 
131
 
 
132
static int
 
133
ngx_http_lua_ngx_re_match_helper(lua_State *L, int wantcaps)
 
134
{
110
135
    /* u_char                      *p; */
 
136
    int                          res_tb_idx = 0;
111
137
    ngx_http_request_t          *r;
112
138
    ngx_str_t                    subj;
113
139
    ngx_str_t                    pat;
123
149
    int                          ovecsize;
124
150
    ngx_uint_t                   flags;
125
151
    ngx_pool_t                  *pool, *old_pool;
126
 
    ngx_http_lua_main_conf_t    *lmcf = NULL;
 
152
    ngx_http_lua_main_conf_t    *lmcf;
127
153
    u_char                       errstr[NGX_MAX_CONF_ERRSTR + 1];
128
154
    pcre_extra                  *sd = NULL;
129
 
    int                          name_entry_size, name_count;
130
 
    u_char                      *name_table;
 
155
    int                          name_entry_size = 0, name_count;
 
156
    u_char                      *name_table = NULL;
 
157
    int                          exec_opts;
 
158
    int                          group_id = 0;
131
159
 
132
160
    ngx_http_lua_regex_compile_t      re_comp;
133
161
 
134
162
    nargs = lua_gettop(L);
135
163
 
136
 
    if (nargs != 2 && nargs != 3 && nargs != 4) {
137
 
        return luaL_error(L, "expecting two or three or four arguments, "
 
164
    if (nargs != 2 && nargs != 3 && nargs != 4 && nargs != 5) {
 
165
        return luaL_error(L, "expecting 2, 3, 4 or 5 arguments, "
138
166
                          "but got %d", nargs);
139
167
    }
140
168
 
141
 
    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
142
 
    lua_rawget(L, LUA_GLOBALSINDEX);
143
 
    r = lua_touserdata(L, -1);
144
 
    lua_pop(L, 1);
145
 
 
 
169
    r = ngx_http_lua_get_req(L);
146
170
    if (r == NULL) {
147
171
        return luaL_error(L, "no request object found");
148
172
    }
160
184
            lua_getfield(L, 4, "pos");
161
185
            if (lua_isnumber(L, -1)) {
162
186
                pos = (ngx_int_t) lua_tointeger(L, -1);
163
 
                if (pos < 0) {
 
187
                if (pos <= 0) {
164
188
                    pos = 0;
 
189
 
 
190
                } else {
 
191
                    pos--;  /* 1-based on the Lua land */
165
192
                }
166
193
 
167
194
            } else if (lua_isnil(L, -1)) {
182
209
        opts.len = 0;
183
210
    }
184
211
 
 
212
    if (nargs == 5) {
 
213
        if (wantcaps) {
 
214
            luaL_checktype(L, 5, LUA_TTABLE);
 
215
            res_tb_idx = 5;
 
216
 
 
217
            /* clear the Lua table */
 
218
            lua_pushnil(L);
 
219
            while (lua_next(L, res_tb_idx) != 0) {
 
220
                lua_pop(L, 1);
 
221
                lua_pushvalue(L, -1);
 
222
                lua_pushnil(L);
 
223
                lua_rawset(L, res_tb_idx);
 
224
            }
 
225
 
 
226
        } else {
 
227
            group_id =  luaL_checkint(L, 5);
 
228
            if (group_id < 0) {
 
229
                group_id = 0;
 
230
            }
 
231
        }
 
232
    }
 
233
 
185
234
    re_comp.options = 0;
186
235
 
187
236
    flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 3);
188
237
 
 
238
    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
 
239
 
189
240
    if (flags & NGX_LUA_RE_COMPILE_ONCE) {
190
 
        lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
191
241
        pool = lmcf->pool;
192
242
 
193
243
        dd("server pool %p", lmcf->pool);
286
336
        dd("compile failed");
287
337
 
288
338
        lua_pushnil(L);
289
 
 
290
 
        re_comp.err.data[re_comp.err.len] = '\0';
291
 
        msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
292
 
                              pat.data, re_comp.err.data);
293
 
 
294
 
        return 2;
 
339
        if (!wantcaps) {
 
340
            lua_pushnil(L);
 
341
        }
 
342
        lua_pushlstring(L, (char *) re_comp.err.data, re_comp.err.len);
 
343
        return wantcaps ? 2 : 3;
295
344
    }
296
345
 
297
346
#if (LUA_HAVE_PCRE_JIT)
355
404
 
356
405
#endif /* LUA_HAVE_PCRE_JIT */
357
406
 
 
407
    if (sd && lmcf->regex_match_limit > 0) {
 
408
        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
 
409
        sd->match_limit = lmcf->regex_match_limit;
 
410
    }
 
411
 
358
412
    dd("compile done, captures %d", (int) re_comp.captures);
359
413
 
360
414
    if (flags & NGX_LUA_RE_MODE_DFA) {
379
433
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
380
434
                       "lua saving compiled regex (%d captures) into the cache "
381
435
                       "(entries %i)", re_comp.captures,
382
 
                       lmcf ? lmcf->regex_cache_entries : 0);
 
436
                       lmcf->regex_cache_entries);
383
437
 
384
438
        re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
385
439
        if (re == NULL) {
429
483
        }
430
484
    }
431
485
 
 
486
    if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
 
487
        exec_opts = PCRE_NO_UTF8_CHECK;
 
488
 
 
489
    } else {
 
490
        exec_opts = 0;
 
491
    }
 
492
 
432
493
    if (flags & NGX_LUA_RE_MODE_DFA) {
433
494
 
434
495
#if LUA_HAVE_PCRE_DFA
436
497
        int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
437
498
        rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,
438
499
                                         (int) pos, cap, ovecsize, ws,
439
 
                                         sizeof(ws)/sizeof(ws[0]));
 
500
                                         sizeof(ws)/sizeof(ws[0]), exec_opts);
440
501
 
441
502
#else /* LUA_HAVE_PCRE_DFA */
442
503
 
447
508
 
448
509
    } else {
449
510
        rc = ngx_http_lua_regex_exec(re_comp.regex, sd, &subj, (int) pos, cap,
450
 
                                     ovecsize);
 
511
                                     ovecsize, exec_opts);
451
512
    }
452
513
 
453
514
    if (rc == NGX_REGEX_NO_MATCHED) {
469
530
    }
470
531
 
471
532
    if (rc < 0) {
472
 
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\" "
473
 
                              "using \"%s\"", (int) rc, subj.data, pat.data);
 
533
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d", (int) rc);
474
534
        goto error;
475
535
    }
476
536
 
486
546
 
487
547
    dd("rc = %d", (int) rc);
488
548
 
489
 
    lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);
490
 
 
491
 
    for (i = 0, n = 0; i < rc; i++, n += 2) {
492
 
        dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
493
 
        if (cap[n] < 0) {
494
 
            lua_pushnil(L);
495
 
 
496
 
        } else {
497
 
            lua_pushlstring(L, (char *) &subj.data[cap[n]],
498
 
                            cap[n + 1] - cap[n]);
499
 
 
500
 
            dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
501
 
        }
502
 
 
503
 
        lua_rawseti(L, -2, (int) i);
504
 
    }
505
 
 
506
 
    if (name_count > 0) {
507
 
        ngx_http_lua_re_collect_named_captures(L, name_table, name_count,
508
 
                                               name_entry_size, flags, &subj);
509
 
    }
510
 
 
511
549
    if (nargs == 4) { /* having ctx table */
512
550
        pos = cap[1];
513
 
        lua_pushinteger(L, (lua_Integer) pos);
 
551
        lua_pushinteger(L, (lua_Integer) (pos + 1));
514
552
        lua_setfield(L, 4, "pos");
515
553
    }
516
554
 
 
555
    if (!wantcaps) {
 
556
        if (group_id > re_comp.captures) {
 
557
            lua_pushnil(L);
 
558
            lua_pushnil(L);
 
559
            lua_pushliteral(L, "nth out of bound");
 
560
            return 3;
 
561
        }
 
562
 
 
563
        if (group_id >= rc) {
 
564
            lua_pushnil(L);
 
565
            lua_pushnil(L);
 
566
            return 2;
 
567
        }
 
568
 
 
569
        {
 
570
            int     from, to;
 
571
 
 
572
            from = cap[group_id * 2] + 1;
 
573
            to = cap[group_id * 2 + 1];
 
574
            if (from < 0 || to < 0) {
 
575
                lua_pushnil(L);
 
576
                lua_pushnil(L);
 
577
                return 2;
 
578
            }
 
579
 
 
580
            lua_pushinteger(L, from);
 
581
            lua_pushinteger(L, to);
 
582
            return 2;
 
583
        }
 
584
    }
 
585
 
 
586
    if (res_tb_idx == 0) {
 
587
        lua_createtable(L, rc /* narr */, 0 /* nrec */);
 
588
        res_tb_idx = lua_gettop(L);
 
589
    }
 
590
 
 
591
    for (i = 0, n = 0; i < rc; i++, n += 2) {
 
592
        dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
 
593
        if (cap[n] < 0) {
 
594
            lua_pushnil(L);
 
595
 
 
596
        } else {
 
597
            lua_pushlstring(L, (char *) &subj.data[cap[n]],
 
598
                            cap[n + 1] - cap[n]);
 
599
 
 
600
            dd("pushing capture %s at %d", lua_tostring(L, -1), (int) i);
 
601
        }
 
602
 
 
603
        lua_rawseti(L, res_tb_idx, (int) i);
 
604
    }
 
605
 
 
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,
 
609
                                               flags, &subj);
 
610
    }
 
611
 
517
612
    if (!(flags & NGX_LUA_RE_COMPILE_ONCE)) {
518
613
 
519
614
        if (sd) {
542
637
    }
543
638
 
544
639
    lua_pushnil(L);
 
640
    if (!wantcaps) {
 
641
        lua_pushnil(L);
 
642
    }
545
643
    lua_pushstring(L, msg);
546
 
    return 2;
 
644
    return wantcaps ? 2 : 3;
547
645
}
548
646
 
549
647
 
550
648
static int
551
649
ngx_http_lua_ngx_re_gmatch(lua_State *L)
552
650
{
553
 
    ngx_http_lua_main_conf_t    *lmcf = NULL;
 
651
    ngx_http_lua_main_conf_t    *lmcf;
554
652
    ngx_http_request_t          *r;
555
653
    ngx_str_t                    subj;
556
654
    ngx_str_t                    pat;
577
675
                nargs);
578
676
    }
579
677
 
580
 
    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
581
 
    lua_rawget(L, LUA_GLOBALSINDEX);
582
 
    r = lua_touserdata(L, -1);
583
 
    lua_pop(L, 1);
584
 
 
 
678
    r = ngx_http_lua_get_req(L);
585
679
    if (r == NULL) {
586
680
        return luaL_error(L, "no request object found");
587
681
    }
604
698
 
605
699
    flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 3);
606
700
 
 
701
    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
 
702
 
607
703
    if (flags & NGX_LUA_RE_COMPILE_ONCE) {
608
 
        lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
609
704
        pool = lmcf->pool;
610
705
 
611
706
        dd("server pool %p", lmcf->pool);
702
797
        dd("compile failed");
703
798
 
704
799
        lua_pushnil(L);
705
 
 
706
 
        re_comp.err.data[re_comp.err.len] = '\0';
707
 
        msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
708
 
                              pat.data, re_comp.err.data);
709
 
 
 
800
        lua_pushlstring(L, (char *) re_comp.err.data, re_comp.err.len);
710
801
        return 2;
711
802
    }
712
803
 
772
863
 
773
864
#endif /* LUA_HAVE_PCRE_JIT */
774
865
 
 
866
    if (sd && lmcf->regex_match_limit > 0) {
 
867
        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
 
868
        sd->match_limit = lmcf->regex_match_limit;
 
869
    }
 
870
 
775
871
    dd("compile done, captures %d", re_comp.captures);
776
872
 
777
873
    if (flags & NGX_LUA_RE_MODE_DFA) {
793
889
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
794
890
                       "lua saving compiled regex (%d captures) into the cache "
795
891
                       "(entries %i)", re_comp.captures,
796
 
                       lmcf ? lmcf->regex_cache_entries : 0);
 
892
                       lmcf->regex_cache_entries);
797
893
 
798
894
        re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
799
895
        if (re == NULL) {
892
988
    ngx_str_t                    subj;
893
989
    int                          offset;
894
990
    const char                  *msg = NULL;
895
 
    int                          name_entry_size, name_count;
896
 
    u_char                      *name_table;
 
991
    int                          name_entry_size = 0, name_count;
 
992
    u_char                      *name_table = NULL;
 
993
    int                          exec_opts;
897
994
 
898
995
    /* upvalues in order: subj ctx offset */
899
996
 
910
1007
 
911
1008
    dd("offset %d, r %p, subj %s", (int) offset, ctx->request, subj.data);
912
1009
 
913
 
    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
914
 
    lua_rawget(L, LUA_GLOBALSINDEX);
915
 
    r = lua_touserdata(L, -1);
916
 
    lua_pop(L, 1);
917
 
 
 
1010
    r = ngx_http_lua_get_req(L);
918
1011
    if (r == NULL) {
919
1012
        return luaL_error(L, "no request object found");
920
1013
    }
949
1042
        }
950
1043
    }
951
1044
 
 
1045
    if (ctx->flags & NGX_LUA_RE_NO_UTF8_CHECK) {
 
1046
        exec_opts = PCRE_NO_UTF8_CHECK;
 
1047
 
 
1048
    } else {
 
1049
        exec_opts = 0;
 
1050
    }
 
1051
 
952
1052
    if (ctx->flags & NGX_LUA_RE_MODE_DFA) {
953
1053
 
954
1054
#if LUA_HAVE_PCRE_DFA
957
1057
 
958
1058
        rc = ngx_http_lua_regex_dfa_exec(ctx->regex, ctx->regex_sd, &subj,
959
1059
                                         offset, cap, ctx->captures_len, ws,
960
 
                                         sizeof(ws)/sizeof(ws[0]));
 
1060
                                         sizeof(ws)/sizeof(ws[0]), exec_opts);
961
1061
 
962
1062
#else /* LUA_HAVE_PCRE_DFA */
963
1063
        msg = "at least pcre 6.0 is required for the DFA mode";
967
1067
 
968
1068
    } else {
969
1069
        rc = ngx_http_lua_regex_exec(ctx->regex, ctx->regex_sd, &subj,
970
 
                                     offset, cap, ctx->captures_len);
 
1070
                                     offset, cap, ctx->captures_len,
 
1071
                                     exec_opts);
971
1072
    }
972
1073
 
973
1074
    if (rc == NGX_REGEX_NO_MATCHED) {
989
1090
    }
990
1091
 
991
1092
    if (rc < 0) {
992
 
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\"",
993
 
                              (int) rc, subj.data);
 
1093
        msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d", (int) rc);
994
1094
        goto error;
995
1095
    }
996
1096
 
1005
1105
 
1006
1106
    dd("rc = %d", (int) rc);
1007
1107
 
1008
 
    lua_createtable(L, rc - 1 /* narr */, 1 /* nrec */);
 
1108
    lua_createtable(L, rc /* narr */, 0 /* nrec */);
1009
1109
 
1010
1110
    for (i = 0, n = 0; i < rc; i++, n += 2) {
1011
1111
        dd("capture %d: %d %d", i, cap[n], cap[n + 1]);
1023
1123
    }
1024
1124
 
1025
1125
    if (name_count > 0) {
1026
 
        ngx_http_lua_re_collect_named_captures(L, name_table, name_count,
1027
 
                                               name_entry_size, ctx->flags,
1028
 
                                               &subj);
 
1126
        ngx_http_lua_re_collect_named_captures(L, lua_gettop(L), name_table,
 
1127
                                               name_count, name_entry_size,
 
1128
                                               ctx->flags, &subj);
1029
1129
    }
1030
1130
 
1031
1131
    offset = cap[1];
1072
1172
 
1073
1173
static ngx_uint_t
1074
1174
ngx_http_lua_ngx_re_parse_opts(lua_State *L, ngx_http_lua_regex_compile_t *re,
1075
 
        ngx_str_t *opts, int narg)
 
1175
    ngx_str_t *opts, int narg)
1076
1176
{
1077
1177
    u_char          *p;
1078
1178
    const char      *msg;
1099
1199
                re->options |= PCRE_UTF8;
1100
1200
                break;
1101
1201
 
 
1202
            case 'U':
 
1203
                re->options |= PCRE_UTF8;
 
1204
                flags |= NGX_LUA_RE_NO_UTF8_CHECK;
 
1205
                break;
 
1206
 
1102
1207
            case 'x':
1103
1208
                re->options |= PCRE_EXTENDED;
1104
1209
                break;
1131
1236
#endif
1132
1237
 
1133
1238
            default:
1134
 
                msg = lua_pushfstring(L, "unknown flag \"%c\"", *p);
 
1239
                msg = lua_pushfstring(L, "unknown flag \"%c\" (flags \"%s\")",
 
1240
                                      *p, opts->data);
1135
1241
                return luaL_argerror(L, narg, msg);
1136
1242
        }
1137
1243
 
1172
1278
    ngx_str_t                    pat;
1173
1279
    ngx_str_t                    opts;
1174
1280
    ngx_str_t                    tpl;
1175
 
    ngx_http_lua_main_conf_t    *lmcf = NULL;
 
1281
    ngx_http_lua_main_conf_t    *lmcf;
1176
1282
    ngx_pool_t                  *pool, *old_pool;
1177
1283
    const char                  *msg;
1178
1284
    ngx_int_t                    rc;
1191
1297
    u_char                      *p;
1192
1298
    u_char                       errstr[NGX_MAX_CONF_ERRSTR + 1];
1193
1299
    pcre_extra                  *sd = NULL;
1194
 
    int                          name_entry_size, name_count;
1195
 
    u_char                      *name_table;
 
1300
    int                          name_entry_size = 0, name_count;
 
1301
    u_char                      *name_table = NULL;
 
1302
    int                          exec_opts;
1196
1303
 
1197
1304
    ngx_http_lua_regex_compile_t               re_comp;
1198
1305
    ngx_http_lua_complex_value_t              *ctpl = NULL;
1205
1312
                nargs);
1206
1313
    }
1207
1314
 
1208
 
    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
1209
 
    lua_rawget(L, LUA_GLOBALSINDEX);
1210
 
    r = lua_touserdata(L, -1);
1211
 
    lua_pop(L, 1);
1212
 
 
 
1315
    r = ngx_http_lua_get_req(L);
1213
1316
    if (r == NULL) {
1214
1317
        return luaL_error(L, "no request object found");
1215
1318
    }
1255
1358
 
1256
1359
    flags = ngx_http_lua_ngx_re_parse_opts(L, &re_comp, &opts, 4);
1257
1360
 
 
1361
    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
 
1362
 
1258
1363
    if (flags & NGX_LUA_RE_COMPILE_ONCE) {
1259
 
        lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
1260
1364
        pool = lmcf->pool;
1261
1365
 
1262
1366
        dd("server pool %p", lmcf->pool);
1373
1477
 
1374
1478
        lua_pushnil(L);
1375
1479
        lua_pushnil(L);
1376
 
 
1377
 
        re_comp.err.data[re_comp.err.len] = '\0';
1378
 
        msg = lua_pushfstring(L, "failed to compile regex \"%s\": %s",
1379
 
                              pat.data, re_comp.err.data);
1380
 
 
 
1480
        lua_pushlstring(L, (char *) re_comp.err.data, re_comp.err.len);
1381
1481
        return 3;
1382
1482
    }
1383
1483
 
1443
1543
 
1444
1544
#endif /* LUA_HAVE_PCRE_JIT */
1445
1545
 
 
1546
    if (sd && lmcf->regex_match_limit > 0) {
 
1547
        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
 
1548
        sd->match_limit = lmcf->regex_match_limit;
 
1549
    }
 
1550
 
1446
1551
    dd("compile done, captures %d", re_comp.captures);
1447
1552
 
1448
1553
    if (flags & NGX_LUA_RE_MODE_DFA) {
1507
1612
 
1508
1613
            lua_pushnil(L);
1509
1614
            lua_pushnil(L);
1510
 
            lua_pushfstring(L, "bad template for substitution: \"%s\"",
1511
 
                            lua_tostring(L, 3));
 
1615
            lua_pushliteral(L, "failed to compile the replacement template");
1512
1616
            return 3;
1513
1617
        }
1514
1618
    }
1518
1622
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1519
1623
                       "lua saving compiled sub regex (%d captures) into "
1520
1624
                       "the cache (entries %i)", re_comp.captures,
1521
 
                       lmcf ? lmcf->regex_cache_entries : 0);
 
1625
                       lmcf->regex_cache_entries);
1522
1626
 
1523
1627
        re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
1524
1628
        if (re == NULL) {
1572
1676
        }
1573
1677
    }
1574
1678
 
 
1679
    if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
 
1680
        exec_opts = PCRE_NO_UTF8_CHECK;
 
1681
 
 
1682
    } else {
 
1683
        exec_opts = 0;
 
1684
    }
 
1685
 
1575
1686
    for (;;) {
1576
1687
        if (flags & NGX_LUA_RE_MODE_DFA) {
1577
1688
 
1580
1691
            int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
1581
1692
            rc = ngx_http_lua_regex_dfa_exec(re_comp.regex, sd, &subj,
1582
1693
                                             offset, cap, ovecsize, ws,
1583
 
                                             sizeof(ws)/sizeof(ws[0]));
 
1694
                                             sizeof(ws)/sizeof(ws[0]),
 
1695
                                             exec_opts);
1584
1696
 
1585
1697
#else /* LUA_HAVE_PCRE_DFA */
1586
1698
 
1587
 
        msg = "at least pcre 6.0 is required for the DFA mode";
1588
 
        goto error;
 
1699
            msg = "at least pcre 6.0 is required for the DFA mode";
 
1700
            goto error;
1589
1701
 
1590
1702
#endif /* LUA_HAVE_PCRE_DFA */
1591
1703
 
1592
1704
        } else {
1593
1705
            rc = ngx_http_lua_regex_exec(re_comp.regex, sd, &subj, offset, cap,
1594
 
                                         ovecsize);
 
1706
                                         ovecsize, exec_opts);
1595
1707
        }
1596
1708
 
1597
1709
        if (rc == NGX_REGEX_NO_MATCHED) {
1599
1711
        }
1600
1712
 
1601
1713
        if (rc < 0) {
1602
 
            msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d on \"%s\" "
1603
 
                                  "using \"%s\"", (int) rc, subj.data,
1604
 
                                  pat.data);
 
1714
            msg = lua_pushfstring(L, ngx_regex_exec_n " failed: %d",
 
1715
                                  (int) rc);
1605
1716
            goto error;
1606
1717
        }
1607
1718
 
1645
1756
            }
1646
1757
 
1647
1758
            if (name_count > 0) {
1648
 
                ngx_http_lua_re_collect_named_captures(L, name_table,
 
1759
                ngx_http_lua_re_collect_named_captures(L, lua_gettop(L),
 
1760
                                                       name_table,
1649
1761
                                                       name_count,
1650
1762
                                                       name_entry_size,
1651
1763
                                                       flags, &subj);
1789
1901
{
1790
1902
    /* ngx.re */
1791
1903
 
1792
 
    lua_newtable(L);    /* .re */
 
1904
    lua_createtable(L, 0, 5 /* nrec */);    /* .re */
 
1905
 
 
1906
    lua_pushcfunction(L, ngx_http_lua_ngx_re_find);
 
1907
    lua_setfield(L, -2, "find");
1793
1908
 
1794
1909
    lua_pushcfunction(L, ngx_http_lua_ngx_re_match);
1795
1910
    lua_setfield(L, -2, "match");
1918
2033
 
1919
2034
 
1920
2035
static void
1921
 
ngx_http_lua_re_collect_named_captures(lua_State *L, u_char *name_table,
1922
 
    int name_count, int name_entry_size, unsigned flags, ngx_str_t *subj)
 
2036
ngx_http_lua_re_collect_named_captures(lua_State *L, int res_tb_idx,
 
2037
    u_char *name_table, int name_count, int name_entry_size, unsigned flags,
 
2038
    ngx_str_t *subj)
1923
2039
{
1924
2040
    int              i, n;
1925
2041
    size_t           len;
1950
2066
                lua_createtable(L, 1 /* narr */, 0 /* nrec */);
1951
2067
                lua_pushstring(L, name);
1952
2068
                lua_pushvalue(L, -2); /* big_tb cap small_tb key small_tb */
1953
 
                lua_rawset(L, -5); /* big_tb cap small_tb */
 
2069
                lua_rawset(L, res_tb_idx); /* big_tb cap small_tb */
1954
2070
                len = 0;
1955
2071
 
1956
2072
            } else {
1964
2080
        } else {
1965
2081
            lua_pushstring(L, name); /* big_tb cap key */
1966
2082
            lua_pushvalue(L, -2); /* big_tb cap key cap */
1967
 
            lua_rawset(L, -4); /* big_tb cap */
 
2083
            lua_rawset(L, res_tb_idx); /* big_tb cap */
1968
2084
            lua_pop(L, 1);
1969
2085
        }
1970
2086
 
1972
2088
    }
1973
2089
}
1974
2090
 
 
2091
 
 
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,
 
2096
    size_t errstr_size)
 
2097
{
 
2098
    int                     *cap = NULL, ovecsize;
 
2099
    u_char                  *p;
 
2100
    ngx_int_t                rc;
 
2101
    const char              *msg;
 
2102
    ngx_pool_t              *pool, *old_pool;
 
2103
    pcre_extra              *sd = NULL;
 
2104
    ngx_http_lua_regex_t    *re;
 
2105
 
 
2106
    ngx_http_lua_main_conf_t         *lmcf;
 
2107
    ngx_http_lua_regex_compile_t      re_comp;
 
2108
 
 
2109
    pool = ngx_create_pool(512, ngx_cycle->log);
 
2110
    if (pool == NULL) {
 
2111
        msg = "no memory";
 
2112
        goto error;
 
2113
    }
 
2114
 
 
2115
    re = ngx_palloc(pool, sizeof(ngx_http_lua_regex_t));
 
2116
    if (re == NULL) {
 
2117
        ngx_destroy_pool(pool);
 
2118
        pool = NULL;
 
2119
        msg = "no memory";
 
2120
        goto error;
 
2121
    }
 
2122
 
 
2123
    re->pool = pool;
 
2124
 
 
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;
 
2131
 
 
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);
 
2135
 
 
2136
    if (rc != NGX_OK) {
 
2137
        re_comp.err.data[re_comp.err.len] = '\0';
 
2138
        msg = (char *) re_comp.err.data;
 
2139
        goto error;
 
2140
    }
 
2141
 
 
2142
#if (LUA_HAVE_PCRE_JIT)
 
2143
 
 
2144
    if (flags & NGX_LUA_RE_MODE_JIT) {
 
2145
 
 
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);
 
2149
 
 
2150
#   if (NGX_DEBUG)
 
2151
        if (msg != NULL) {
 
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);
 
2155
        }
 
2156
 
 
2157
        if (sd != NULL) {
 
2158
            int         jitted;
 
2159
 
 
2160
            old_pool = ngx_http_lua_pcre_malloc_init(pool);
 
2161
 
 
2162
            pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);
 
2163
 
 
2164
            ngx_http_lua_pcre_malloc_done(old_pool);
 
2165
 
 
2166
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
 
2167
                           "pcre JIT compiling result: %d", jitted);
 
2168
        }
 
2169
#   endif /* !(NGX_DEBUG) */
 
2170
 
 
2171
    } else {
 
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);
 
2175
    }
 
2176
 
 
2177
#endif /* LUA_HAVE_PCRE_JIT */
 
2178
 
 
2179
    lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
 
2180
                                               ngx_http_lua_module);
 
2181
 
 
2182
    if (sd && lmcf && lmcf->regex_match_limit > 0) {
 
2183
        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
 
2184
        sd->match_limit = lmcf->regex_match_limit;
 
2185
    }
 
2186
 
 
2187
    if (flags & NGX_LUA_RE_MODE_DFA) {
 
2188
        ovecsize = 2;
 
2189
 
 
2190
    } else {
 
2191
        ovecsize = (re_comp.captures + 1) * 3;
 
2192
    }
 
2193
 
 
2194
    dd("allocating cap with size: %d", (int) ovecsize);
 
2195
 
 
2196
    cap = ngx_palloc(pool, ovecsize * sizeof(int));
 
2197
    if (cap == NULL) {
 
2198
        msg = "no memory";
 
2199
        goto error;
 
2200
    }
 
2201
 
 
2202
    if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMECOUNT,
 
2203
                      &re->name_count) != 0)
 
2204
    {
 
2205
        msg = "cannot acquire named subpattern count";
 
2206
        goto error;
 
2207
    }
 
2208
 
 
2209
    if (re->name_count > 0) {
 
2210
        if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMEENTRYSIZE,
 
2211
                          &re->name_entry_size) != 0)
 
2212
        {
 
2213
            msg = "cannot acquire named subpattern entry size";
 
2214
            goto error;
 
2215
        }
 
2216
 
 
2217
        if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMETABLE,
 
2218
                          &re->name_table) != 0)
 
2219
        {
 
2220
            msg = "cannot acquire named subpattern table";
 
2221
            goto error;
 
2222
        }
 
2223
    }
 
2224
 
 
2225
    re->regex = re_comp.regex;
 
2226
    re->regex_sd = sd;
 
2227
    re->ncaptures = re_comp.captures;
 
2228
    re->captures = cap;
 
2229
    re->replace = NULL;
 
2230
 
 
2231
    return re;
 
2232
 
 
2233
error:
 
2234
    p = ngx_snprintf(errstr, errstr_size - 1, "%s", msg);
 
2235
    *p = '\0';
 
2236
 
 
2237
    if (sd) {
 
2238
        ngx_http_lua_regex_free_study_data(pool, sd);
 
2239
    }
 
2240
 
 
2241
    if (pool) {
 
2242
        ngx_destroy_pool(pool);
 
2243
    }
 
2244
 
 
2245
    return NULL;
 
2246
}
 
2247
 
 
2248
 
 
2249
int
 
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)
 
2252
{
 
2253
    int             rc, ovecsize, exec_opts, *cap;
 
2254
    ngx_str_t       subj;
 
2255
    pcre_extra     *sd;
 
2256
 
 
2257
    cap = re->captures;
 
2258
    sd = re->regex_sd;
 
2259
 
 
2260
    if (flags & NGX_LUA_RE_MODE_DFA) {
 
2261
        ovecsize = 2;
 
2262
 
 
2263
    } else {
 
2264
        ovecsize = (re->ncaptures + 1) * 3;
 
2265
    }
 
2266
 
 
2267
    if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
 
2268
        exec_opts = PCRE_NO_UTF8_CHECK;
 
2269
 
 
2270
    } else {
 
2271
        exec_opts = 0;
 
2272
    }
 
2273
 
 
2274
    subj.data = (u_char *) s;
 
2275
    subj.len = len;
 
2276
 
 
2277
    if (flags & NGX_LUA_RE_MODE_DFA) {
 
2278
 
 
2279
#if LUA_HAVE_PCRE_DFA
 
2280
 
 
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);
 
2285
 
 
2286
#else /* LUA_HAVE_PCRE_DFA */
 
2287
 
 
2288
        return PCRE_ERROR_INTERNAL;
 
2289
 
 
2290
#endif /* LUA_HAVE_PCRE_DFA */
 
2291
 
 
2292
    } else {
 
2293
        rc = ngx_http_lua_regex_exec(re->regex, sd, &subj, (int) pos, cap,
 
2294
                                     ovecsize, exec_opts);
 
2295
    }
 
2296
 
 
2297
    return rc;
 
2298
}
 
2299
 
 
2300
 
 
2301
void
 
2302
ngx_http_lua_ffi_destroy_regex(ngx_http_lua_regex_t *re)
 
2303
{
 
2304
    dd("destroy regex called");
 
2305
 
 
2306
    if (re == NULL || re->pool == NULL) {
 
2307
        return;
 
2308
    }
 
2309
 
 
2310
    if (re->regex_sd) {
 
2311
#if LUA_HAVE_PCRE_JIT
 
2312
        pcre_free_study(re->regex_sd);
 
2313
#else
 
2314
        pcre_free(re->regex_sd);
 
2315
#endif
 
2316
    }
 
2317
 
 
2318
    ngx_destroy_pool(re->pool);
 
2319
}
 
2320
 
 
2321
 
 
2322
int
 
2323
ngx_http_lua_ffi_compile_replace_template(ngx_http_lua_regex_t *re,
 
2324
    const u_char *replace_data, size_t replace_len)
 
2325
{
 
2326
    ngx_int_t                                rc;
 
2327
    ngx_str_t                                tpl;
 
2328
    ngx_http_lua_complex_value_t            *ctpl;
 
2329
    ngx_http_lua_compile_complex_value_t     ccv;
 
2330
 
 
2331
    ctpl = ngx_palloc(re->pool, sizeof(ngx_http_lua_complex_value_t));
 
2332
    if (ctpl == NULL) {
 
2333
        return NGX_ERROR;
 
2334
    }
 
2335
 
 
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) {
 
2340
            return NGX_ERROR;
 
2341
        }
 
2342
 
 
2343
        ngx_memcpy(tpl.data, replace_data, replace_len);
 
2344
        tpl.data[replace_len] = '\0';
 
2345
 
 
2346
    } else {
 
2347
        tpl.data = (u_char *) replace_data;
 
2348
    }
 
2349
 
 
2350
    tpl.len = replace_len;
 
2351
 
 
2352
    ngx_memzero(&ccv, sizeof(ngx_http_lua_compile_complex_value_t));
 
2353
    ccv.pool = re->pool;
 
2354
    ccv.log = ngx_cycle->log;
 
2355
    ccv.value = &tpl;
 
2356
    ccv.complex_value = ctpl;
 
2357
 
 
2358
    rc = ngx_http_lua_compile_complex_value(&ccv);
 
2359
 
 
2360
    re->replace = ctpl;
 
2361
 
 
2362
    return rc;
 
2363
}
 
2364
 
 
2365
 
 
2366
ngx_http_lua_script_engine_t *
 
2367
ngx_http_lua_ffi_create_script_engine(void)
 
2368
{
 
2369
    return ngx_calloc(sizeof(ngx_http_lua_script_engine_t), ngx_cycle->log);
 
2370
}
 
2371
 
 
2372
 
 
2373
void
 
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)
 
2376
{
 
2377
    e->log = ngx_cycle->log;
 
2378
    e->ncaptures = count * 2;
 
2379
    e->captures = compiled->captures;
 
2380
    e->captures_data = (u_char *) subj;
 
2381
}
 
2382
 
 
2383
 
 
2384
void
 
2385
ngx_http_lua_ffi_destroy_script_engine(ngx_http_lua_script_engine_t *e)
 
2386
{
 
2387
    ngx_free(e);
 
2388
}
 
2389
 
 
2390
 
 
2391
size_t
 
2392
ngx_http_lua_ffi_script_eval_len(ngx_http_lua_script_engine_t *e,
 
2393
    ngx_http_lua_complex_value_t *val)
 
2394
{
 
2395
    size_t          len;
 
2396
 
 
2397
    ngx_http_lua_script_len_code_pt   lcode;
 
2398
 
 
2399
    e->ip = val->lengths;
 
2400
    len = 0;
 
2401
 
 
2402
    while (*(uintptr_t *) e->ip) {
 
2403
        lcode = *(ngx_http_lua_script_len_code_pt *) e->ip;
 
2404
        len += lcode(e);
 
2405
    }
 
2406
 
 
2407
    return len;
 
2408
}
 
2409
 
 
2410
 
 
2411
void
 
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)
 
2414
{
 
2415
    ngx_http_lua_script_code_pt       code;
 
2416
 
 
2417
    e->ip = val->values;
 
2418
    e->pos = dst;
 
2419
 
 
2420
    while (*(uintptr_t *) e->ip) {
 
2421
        code = *(ngx_http_lua_script_code_pt *) e->ip;
 
2422
        code(e);
 
2423
    }
 
2424
}
 
2425
 
 
2426
 
 
2427
uint32_t
 
2428
ngx_http_lua_ffi_max_regex_cache_size(void)
 
2429
{
 
2430
    ngx_http_lua_main_conf_t    *lmcf;
 
2431
    lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
 
2432
                                               ngx_http_lua_module);
 
2433
    if (lmcf == NULL) {
 
2434
        return 0;
 
2435
    }
 
2436
    return (uint32_t) lmcf->regex_cache_max_entries;
 
2437
}
 
2438
#endif /* NGX_HTTP_LUA_NO_FFI_API */
 
2439
 
 
2440
 
1975
2441
#endif /* NGX_PCRE */
1976
2442
 
1977
2443
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */