LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_script.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 0 222 0.0 %
Date: 2020-03-03 04:25:50 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Yichun Zhang (agentzh)
       4             :  */
       5             : 
       6             : 
       7             : #ifndef DDEBUG
       8             : #define DDEBUG 0
       9             : #endif
      10             : #include "ddebug.h"
      11             : 
      12             : 
      13             : #include "ngx_http_lua_script.h"
      14             : 
      15             : 
      16             : static void *ngx_http_lua_script_add_code(ngx_array_t *codes, size_t size);
      17             : static size_t ngx_http_lua_script_copy_len_code(
      18             :     ngx_http_lua_script_engine_t *e);
      19             : static void ngx_http_lua_script_copy_code(ngx_http_lua_script_engine_t *e);
      20             : static ngx_int_t ngx_http_lua_script_add_copy_code(
      21             :     ngx_http_lua_script_compile_t *sc, ngx_str_t *value, ngx_uint_t last);
      22             : static ngx_int_t ngx_http_lua_script_compile(ngx_http_lua_script_compile_t *sc);
      23             : static ngx_int_t ngx_http_lua_script_add_capture_code(
      24             :     ngx_http_lua_script_compile_t *sc, ngx_uint_t n);
      25             : static size_t ngx_http_lua_script_copy_capture_len_code(
      26             :     ngx_http_lua_script_engine_t *e);
      27             : static void ngx_http_lua_script_copy_capture_code(
      28             :     ngx_http_lua_script_engine_t *e);
      29             : static ngx_int_t ngx_http_lua_script_done(ngx_http_lua_script_compile_t *sc);
      30             : static ngx_int_t ngx_http_lua_script_init_arrays(
      31             :     ngx_http_lua_script_compile_t *sc);
      32             : 
      33             : 
      34             : ngx_int_t
      35           0 : ngx_http_lua_compile_complex_value(ngx_http_lua_compile_complex_value_t *ccv)
      36             : {
      37             :     ngx_str_t                  *v;
      38             :     ngx_uint_t                  i, n, nv;
      39             :     ngx_array_t                 lengths, values, *pl, *pv;
      40             : 
      41             :     ngx_http_lua_script_compile_t   sc;
      42             : 
      43           0 :     v = ccv->value;
      44             : 
      45           0 :     nv = 0;
      46             : 
      47           0 :     for (i = 0; i < v->len; i++) {
      48           0 :         if (v->data[i] == '$') {
      49           0 :             nv++;
      50             :         }
      51             :     }
      52             : 
      53           0 :     ccv->complex_value->value = *v;
      54           0 :     ccv->complex_value->lengths = NULL;
      55           0 :     ccv->complex_value->values = NULL;
      56             : 
      57           0 :     if (nv == 0) {
      58           0 :         return NGX_OK;
      59             :     }
      60             : 
      61           0 :     n = nv * (2 * sizeof(ngx_http_lua_script_copy_code_t)
      62             :               + sizeof(ngx_http_lua_script_capture_code_t))
      63             :         + sizeof(uintptr_t);
      64             : 
      65           0 :     if (ngx_array_init(&lengths, ccv->pool, n, 1) != NGX_OK) {
      66           0 :         return NGX_ERROR;
      67             :     }
      68             : 
      69           0 :     n = (nv * (2 * sizeof(ngx_http_lua_script_copy_code_t)
      70             :                    + sizeof(ngx_http_lua_script_capture_code_t))
      71             :                 + sizeof(uintptr_t)
      72           0 :                 + sizeof(uintptr_t) - 1)
      73             :             & ~(sizeof(uintptr_t) - 1);
      74             : 
      75           0 :     if (ngx_array_init(&values, ccv->pool, n, 1) != NGX_OK) {
      76           0 :         return NGX_ERROR;
      77             :     }
      78             : 
      79           0 :     pl = &lengths;
      80           0 :     pv = &values;
      81             : 
      82           0 :     ngx_memzero(&sc, sizeof(ngx_http_lua_script_compile_t));
      83             : 
      84           0 :     sc.pool = ccv->pool;
      85           0 :     sc.log = ccv->log;
      86           0 :     sc.source = v;
      87           0 :     sc.lengths = &pl;
      88           0 :     sc.values = &pv;
      89           0 :     sc.complete_lengths = 1;
      90           0 :     sc.complete_values = 1;
      91             : 
      92           0 :     if (ngx_http_lua_script_compile(&sc) != NGX_OK) {
      93           0 :         ngx_array_destroy(&lengths);
      94           0 :         ngx_array_destroy(&values);
      95           0 :         return NGX_ERROR;
      96             :     }
      97             : 
      98           0 :     ccv->complex_value->lengths = lengths.elts;
      99           0 :     ccv->complex_value->values = values.elts;
     100             : 
     101           0 :     return NGX_OK;
     102             : }
     103             : 
     104             : 
     105             : ngx_int_t
     106           0 : ngx_http_lua_complex_value(ngx_http_request_t *r, ngx_str_t *subj,
     107             :     size_t offset, ngx_int_t count, int *cap,
     108             :     ngx_http_lua_complex_value_t *val, luaL_Buffer *luabuf)
     109             : {
     110             :     size_t                            len;
     111             :     u_char                           *p;
     112             :     ngx_http_lua_script_code_pt       code;
     113             :     ngx_http_lua_script_len_code_pt   lcode;
     114             :     ngx_http_lua_script_engine_t      e;
     115             : 
     116           0 :     if (val->lengths == NULL) {
     117           0 :         luaL_addlstring(luabuf, (char *) &subj->data[offset], cap[0] - offset);
     118           0 :         luaL_addlstring(luabuf, (char *) val->value.data, val->value.len);
     119             : 
     120           0 :         return NGX_OK;
     121             :     }
     122             : 
     123           0 :     ngx_memzero(&e, sizeof(ngx_http_lua_script_engine_t));
     124             : 
     125           0 :     e.log = r->connection->log;
     126           0 :     e.ncaptures = count * 2;
     127           0 :     e.captures = cap;
     128           0 :     e.captures_data = subj->data;
     129             : 
     130           0 :     e.ip = val->lengths;
     131             : 
     132           0 :     len = 0;
     133             : 
     134           0 :     while (*(uintptr_t *) e.ip) {
     135           0 :         lcode = *(ngx_http_lua_script_len_code_pt *) e.ip;
     136           0 :         len += lcode(&e);
     137             :     }
     138             : 
     139           0 :     p = ngx_pnalloc(r->pool, len);
     140           0 :     if (p == NULL) {
     141           0 :         return NGX_ERROR;
     142             :     }
     143             : 
     144           0 :     e.ip = val->values;
     145           0 :     e.pos = p;
     146             : 
     147           0 :     while (*(uintptr_t *) e.ip) {
     148           0 :         code = *(ngx_http_lua_script_code_pt *) e.ip;
     149           0 :         code((ngx_http_lua_script_engine_t *) &e);
     150             :     }
     151             : 
     152           0 :     luaL_addlstring(luabuf, (char *) &subj->data[offset], cap[0] - offset);
     153           0 :     luaL_addlstring(luabuf, (char *) p, len);
     154             : 
     155           0 :     ngx_pfree(r->pool, p);
     156             : 
     157           0 :     return NGX_OK;
     158             : }
     159             : 
     160             : 
     161             : static ngx_int_t
     162           0 : ngx_http_lua_script_compile(ngx_http_lua_script_compile_t *sc)
     163             : {
     164             :     u_char       ch;
     165             :     ngx_str_t    name;
     166             :     ngx_uint_t   i, bracket;
     167             :     unsigned     num_var;
     168           0 :     ngx_uint_t   n = 0;
     169             : 
     170           0 :     if (ngx_http_lua_script_init_arrays(sc) != NGX_OK) {
     171           0 :         return NGX_ERROR;
     172             :     }
     173             : 
     174           0 :     for (i = 0; i < sc->source->len; /* void */ ) {
     175             : 
     176           0 :         name.len = 0;
     177             : 
     178           0 :         if (sc->source->data[i] == '$') {
     179             : 
     180           0 :             if (++i == sc->source->len) {
     181           0 :                 goto invalid_variable;
     182             :             }
     183             : 
     184           0 :             if (sc->source->data[i] == '$') {
     185           0 :                 name.data = &sc->source->data[i];
     186           0 :                 i++;
     187           0 :                 name.len++;
     188             : 
     189           0 :                 if (ngx_http_lua_script_add_copy_code(sc, &name,
     190           0 :                                                       (i == sc->source->len))
     191             :                     != NGX_OK)
     192             :                 {
     193           0 :                     return NGX_ERROR;
     194             :                 }
     195             : 
     196           0 :                 continue;
     197             :             }
     198             : 
     199           0 :             if (sc->source->data[i] >= '0' && sc->source->data[i] <= '9') {
     200           0 :                 num_var = 1;
     201           0 :                 n = 0;
     202             : 
     203             :             } else {
     204           0 :                 num_var = 0;
     205             :             }
     206             : 
     207           0 :             if (sc->source->data[i] == '{') {
     208           0 :                 bracket = 1;
     209             : 
     210           0 :                 if (++i == sc->source->len) {
     211           0 :                     goto invalid_variable;
     212             :                 }
     213             : 
     214           0 :                 if (sc->source->data[i] >= '0' && sc->source->data[i] <= '9') {
     215           0 :                     num_var = 1;
     216           0 :                     n = 0;
     217             :                 }
     218             : 
     219           0 :                 name.data = &sc->source->data[i];
     220             : 
     221             :             } else {
     222           0 :                 bracket = 0;
     223           0 :                 name.data = &sc->source->data[i];
     224             :             }
     225             : 
     226           0 :             for ( /* void */ ; i < sc->source->len; i++, name.len++) {
     227           0 :                 ch = sc->source->data[i];
     228             : 
     229           0 :                 if (ch == '}' && bracket) {
     230           0 :                     i++;
     231           0 :                     bracket = 0;
     232           0 :                     break;
     233             :                 }
     234             : 
     235           0 :                 if (num_var) {
     236           0 :                     if (ch >= '0' && ch <= '9') {
     237           0 :                         n = n * 10 + (ch - '0');
     238           0 :                         continue;
     239             :                     }
     240             : 
     241           0 :                     break;
     242             :                 }
     243             : 
     244             :                 /* not a number variable like $1, $2, etc */
     245             : 
     246           0 :                 if ((ch >= 'A' && ch <= 'Z')
     247           0 :                     || (ch >= 'a' && ch <= 'z')
     248           0 :                     || (ch >= '0' && ch <= '9')
     249           0 :                     || ch == '_')
     250             :                 {
     251           0 :                     continue;
     252             :                 }
     253             : 
     254           0 :                 break;
     255             :             }
     256             : 
     257           0 :             if (bracket) {
     258           0 :                 ngx_log_error(NGX_LOG_ERR, sc->log, 0,
     259             :                               "the closing bracket in \"%V\" "
     260             :                               "variable is missing", &name);
     261           0 :                 return NGX_ERROR;
     262             :             }
     263             : 
     264           0 :             if (name.len == 0) {
     265           0 :                 goto invalid_variable;
     266             :             }
     267             : 
     268           0 :             if (!num_var) {
     269           0 :                 ngx_log_error(NGX_LOG_ERR, sc->log, 0,
     270             :                               "attempt to use named capturing variable "
     271             :                               "\"%V\" (named captures not supported yet)",
     272             :                               &name);
     273             : 
     274           0 :                 return NGX_ERROR;
     275             :             }
     276             : 
     277           0 :             sc->variables++;
     278             : 
     279           0 :             if (ngx_http_lua_script_add_capture_code(sc, n) != NGX_OK) {
     280           0 :                 return NGX_ERROR;
     281             :             }
     282             : 
     283           0 :             continue;
     284             :         }
     285             : 
     286           0 :         name.data = &sc->source->data[i];
     287             : 
     288           0 :         while (i < sc->source->len) {
     289             : 
     290           0 :             if (sc->source->data[i] == '$') {
     291           0 :                 break;
     292             :             }
     293             : 
     294           0 :             i++;
     295           0 :             name.len++;
     296             :         }
     297             : 
     298           0 :         if (ngx_http_lua_script_add_copy_code(sc, &name, (i == sc->source->len))
     299             :             != NGX_OK)
     300             :         {
     301           0 :             return NGX_ERROR;
     302             :         }
     303             :     }
     304             : 
     305           0 :     return ngx_http_lua_script_done(sc);
     306             : 
     307           0 : invalid_variable:
     308             : 
     309           0 :     ngx_log_error(NGX_LOG_ERR, sc->log, 0,
     310             :                   "lua script: invalid capturing variable name found in \"%V\"",
     311             :                   sc->source);
     312             : 
     313           0 :     return NGX_ERROR;
     314             : }
     315             : 
     316             : 
     317             : static ngx_int_t
     318           0 : ngx_http_lua_script_add_copy_code(ngx_http_lua_script_compile_t *sc,
     319             :     ngx_str_t *value, ngx_uint_t last)
     320             : {
     321             :     size_t                            size, len;
     322             :     ngx_http_lua_script_copy_code_t  *code;
     323             : 
     324           0 :     len = value->len;
     325             : 
     326           0 :     code = ngx_http_lua_script_add_code(*sc->lengths,
     327             :                                     sizeof(ngx_http_lua_script_copy_code_t));
     328           0 :     if (code == NULL) {
     329           0 :         return NGX_ERROR;
     330             :     }
     331             : 
     332           0 :     code->code = (ngx_http_lua_script_code_pt)
     333             :                  ngx_http_lua_script_copy_len_code;
     334           0 :     code->len = len;
     335             : 
     336           0 :     size = (sizeof(ngx_http_lua_script_copy_code_t) + len +
     337           0 :             sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1);
     338             : 
     339           0 :     code = ngx_http_lua_script_add_code(*sc->values, size);
     340           0 :     if (code == NULL) {
     341           0 :         return NGX_ERROR;
     342             :     }
     343             : 
     344           0 :     code->code = ngx_http_lua_script_copy_code;
     345           0 :     code->len = len;
     346             : 
     347           0 :     ngx_memcpy((u_char *) code + sizeof(ngx_http_lua_script_copy_code_t),
     348             :                value->data, value->len);
     349             : 
     350           0 :     return NGX_OK;
     351             : }
     352             : 
     353             : 
     354             : static size_t
     355           0 : ngx_http_lua_script_copy_len_code(ngx_http_lua_script_engine_t *e)
     356             : {
     357             :     ngx_http_lua_script_copy_code_t  *code;
     358             : 
     359           0 :     code = (ngx_http_lua_script_copy_code_t *) e->ip;
     360             : 
     361           0 :     e->ip += sizeof(ngx_http_lua_script_copy_code_t);
     362             : 
     363           0 :     return code->len;
     364             : }
     365             : 
     366             : 
     367             : static void
     368           0 : ngx_http_lua_script_copy_code(ngx_http_lua_script_engine_t *e)
     369             : {
     370             :     u_char                           *p;
     371             :     ngx_http_lua_script_copy_code_t  *code;
     372             : 
     373           0 :     code = (ngx_http_lua_script_copy_code_t *) e->ip;
     374             : 
     375           0 :     p = e->pos;
     376             : 
     377           0 :     if (!e->skip) {
     378           0 :         e->pos = ngx_copy(p, e->ip + sizeof(ngx_http_lua_script_copy_code_t),
     379             :                           code->len);
     380             :     }
     381             : 
     382           0 :     e->ip += sizeof(ngx_http_lua_script_copy_code_t)
     383           0 :           + ((code->len + sizeof(uintptr_t) - 1) & ~(sizeof(uintptr_t) - 1));
     384             : 
     385           0 :     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->log, 0,
     386             :                    "lua script copy: \"%*s\"", e->pos - p, p);
     387           0 : }
     388             : 
     389             : 
     390             : static ngx_int_t
     391           0 : ngx_http_lua_script_add_capture_code(ngx_http_lua_script_compile_t *sc,
     392             :     ngx_uint_t n)
     393             : {
     394             :     ngx_http_lua_script_capture_code_t  *code;
     395             : 
     396           0 :     code = ngx_http_lua_script_add_code(*sc->lengths,
     397             :                                   sizeof(ngx_http_lua_script_capture_code_t));
     398           0 :     if (code == NULL) {
     399           0 :         return NGX_ERROR;
     400             :     }
     401             : 
     402           0 :     code->code = (ngx_http_lua_script_code_pt)
     403             :                  ngx_http_lua_script_copy_capture_len_code;
     404           0 :     code->n = 2 * n;
     405             : 
     406           0 :     code = ngx_http_lua_script_add_code(*sc->values,
     407             :                                   sizeof(ngx_http_lua_script_capture_code_t));
     408           0 :     if (code == NULL) {
     409           0 :         return NGX_ERROR;
     410             :     }
     411             : 
     412           0 :     code->code = ngx_http_lua_script_copy_capture_code;
     413           0 :     code->n = 2 * n;
     414             : 
     415           0 :     return NGX_OK;
     416             : }
     417             : 
     418             : 
     419             : static size_t
     420           0 : ngx_http_lua_script_copy_capture_len_code(ngx_http_lua_script_engine_t *e)
     421             : {
     422             :     int                                  *cap;
     423             :     ngx_uint_t                            n;
     424             :     ngx_http_lua_script_capture_code_t   *code;
     425             : 
     426           0 :     code = (ngx_http_lua_script_capture_code_t *) e->ip;
     427             : 
     428           0 :     e->ip += sizeof(ngx_http_lua_script_capture_code_t);
     429             : 
     430           0 :     n = code->n;
     431             : 
     432           0 :     if (n < e->ncaptures) {
     433           0 :         cap = e->captures;
     434           0 :         return cap[n + 1] - cap[n];
     435             :     }
     436             : 
     437           0 :     return 0;
     438             : }
     439             : 
     440             : 
     441             : static void
     442           0 : ngx_http_lua_script_copy_capture_code(ngx_http_lua_script_engine_t *e)
     443             : {
     444             :     int                                  *cap;
     445             :     u_char                               *p, *pos;
     446             :     ngx_uint_t                            n;
     447             :     ngx_http_lua_script_capture_code_t   *code;
     448             : 
     449           0 :     code = (ngx_http_lua_script_capture_code_t *) e->ip;
     450             : 
     451           0 :     e->ip += sizeof(ngx_http_lua_script_capture_code_t);
     452             : 
     453           0 :     n = code->n;
     454             : 
     455           0 :     pos = e->pos;
     456             : 
     457           0 :     if (n < e->ncaptures) {
     458             : 
     459           0 :         cap = e->captures;
     460           0 :         p = e->captures_data;
     461             : 
     462           0 :         e->pos = ngx_copy(pos, &p[cap[n]], cap[n + 1] - cap[n]);
     463             :     }
     464             : 
     465           0 :     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, e->log, 0,
     466             :                    "lua script capture: \"%*s\"", e->pos - pos, pos);
     467           0 : }
     468             : 
     469             : 
     470             : static ngx_int_t
     471           0 : ngx_http_lua_script_init_arrays(ngx_http_lua_script_compile_t *sc)
     472             : {
     473             :     ngx_uint_t   n;
     474             : 
     475           0 :     if (*sc->lengths == NULL) {
     476           0 :         n = sc->variables * (2 * sizeof(ngx_http_lua_script_copy_code_t)
     477             :                              + sizeof(ngx_http_lua_script_capture_code_t))
     478             :             + sizeof(uintptr_t);
     479             : 
     480           0 :         *sc->lengths = ngx_array_create(sc->pool, n, 1);
     481           0 :         if (*sc->lengths == NULL) {
     482           0 :             return NGX_ERROR;
     483             :         }
     484             :     }
     485             : 
     486           0 :     if (*sc->values == NULL) {
     487           0 :         n = (sc->variables * (2 * sizeof(ngx_http_lua_script_copy_code_t)
     488             :                               + sizeof(ngx_http_lua_script_capture_code_t))
     489             :                 + sizeof(uintptr_t)
     490           0 :                 + sizeof(uintptr_t) - 1)
     491             :             & ~(sizeof(uintptr_t) - 1);
     492             : 
     493           0 :         *sc->values = ngx_array_create(sc->pool, n, 1);
     494           0 :         if (*sc->values == NULL) {
     495           0 :             return NGX_ERROR;
     496             :         }
     497             :     }
     498             : 
     499           0 :     sc->variables = 0;
     500             : 
     501           0 :     return NGX_OK;
     502             : }
     503             : 
     504             : 
     505             : static ngx_int_t
     506           0 : ngx_http_lua_script_done(ngx_http_lua_script_compile_t *sc)
     507             : {
     508             :     uintptr_t   *code;
     509             : 
     510           0 :     if (sc->complete_lengths) {
     511           0 :         code = ngx_http_lua_script_add_code(*sc->lengths, sizeof(uintptr_t));
     512           0 :         if (code == NULL) {
     513           0 :             return NGX_ERROR;
     514             :         }
     515             : 
     516           0 :         *code = (uintptr_t) NULL;
     517             :     }
     518             : 
     519           0 :     if (sc->complete_values) {
     520           0 :         code = ngx_http_lua_script_add_code(*sc->values, sizeof(uintptr_t));
     521           0 :         if (code == NULL) {
     522           0 :             return NGX_ERROR;
     523             :         }
     524             : 
     525           0 :         *code = (uintptr_t) NULL;
     526             :     }
     527             : 
     528           0 :     return NGX_OK;
     529             : }
     530             : 
     531             : 
     532             : static void *
     533           0 : ngx_http_lua_script_add_code(ngx_array_t *codes, size_t size)
     534             : {
     535           0 :     return ngx_array_push_n(codes, size);
     536             : }
     537             : 
     538             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13