Annotation of embedaddon/lighttpd/src/mod_ssi_expr.c, revision 1.1.1.1

1.1       misho       1: #include "buffer.h"
                      2: #include "log.h"
                      3: #include "mod_ssi.h"
                      4: #include "mod_ssi_expr.h"
                      5: #include "mod_ssi_exprparser.h"
                      6: 
                      7: #include <ctype.h>
                      8: #include <string.h>
                      9: 
                     10: typedef struct {
                     11:        const char *input;
                     12:        size_t offset;
                     13:        size_t size;
                     14: 
                     15:        int line_pos;
                     16: 
                     17:        int in_key;
                     18:        int in_brace;
                     19:        int in_cond;
                     20: } ssi_tokenizer_t;
                     21: 
                     22: ssi_val_t *ssi_val_init(void) {
                     23:        ssi_val_t *s;
                     24: 
                     25:        s = calloc(1, sizeof(*s));
                     26: 
                     27:        return s;
                     28: }
                     29: 
                     30: void ssi_val_free(ssi_val_t *s) {
                     31:        if (s->str) buffer_free(s->str);
                     32: 
                     33:        free(s);
                     34: }
                     35: 
                     36: int ssi_val_tobool(ssi_val_t *B) {
                     37:        if (B->type == SSI_TYPE_STRING) {
                     38:                return B->str->used > 1 ? 1 : 0;
                     39:        } else {
                     40:                return B->bo;
                     41:        }
                     42: }
                     43: 
                     44: static int ssi_expr_tokenizer(server *srv, connection *con, plugin_data *p,
                     45:                              ssi_tokenizer_t *t, int *token_id, buffer *token) {
                     46:        int tid = 0;
                     47:        size_t i;
                     48: 
                     49:        UNUSED(con);
                     50: 
                     51:        for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) {
                     52:                char c = t->input[t->offset];
                     53:                data_string *ds;
                     54: 
                     55:                switch (c) {
                     56:                case '=':
                     57:                        tid = TK_EQ;
                     58: 
                     59:                        t->offset++;
                     60:                        t->line_pos++;
                     61: 
                     62:                        buffer_copy_string_len(token, CONST_STR_LEN("(=)"));
                     63: 
                     64:                        break;
                     65:                case '>':
                     66:                        if (t->input[t->offset + 1] == '=') {
                     67:                                t->offset += 2;
                     68:                                t->line_pos += 2;
                     69: 
                     70:                                tid = TK_GE;
                     71: 
                     72:                                buffer_copy_string_len(token, CONST_STR_LEN("(>=)"));
                     73:                        } else {
                     74:                                t->offset += 1;
                     75:                                t->line_pos += 1;
                     76: 
                     77:                                tid = TK_GT;
                     78: 
                     79:                                buffer_copy_string_len(token, CONST_STR_LEN("(>)"));
                     80:                        }
                     81: 
                     82:                        break;
                     83:                case '<':
                     84:                        if (t->input[t->offset + 1] == '=') {
                     85:                                t->offset += 2;
                     86:                                t->line_pos += 2;
                     87: 
                     88:                                tid = TK_LE;
                     89: 
                     90:                                buffer_copy_string_len(token, CONST_STR_LEN("(<=)"));
                     91:                        } else {
                     92:                                t->offset += 1;
                     93:                                t->line_pos += 1;
                     94: 
                     95:                                tid = TK_LT;
                     96: 
                     97:                                buffer_copy_string_len(token, CONST_STR_LEN("(<)"));
                     98:                        }
                     99: 
                    100:                        break;
                    101: 
                    102:                case '!':
                    103:                        if (t->input[t->offset + 1] == '=') {
                    104:                                t->offset += 2;
                    105:                                t->line_pos += 2;
                    106: 
                    107:                                tid = TK_NE;
                    108: 
                    109:                                buffer_copy_string_len(token, CONST_STR_LEN("(!=)"));
                    110:                        } else {
                    111:                                t->offset += 1;
                    112:                                t->line_pos += 1;
                    113: 
                    114:                                tid = TK_NOT;
                    115: 
                    116:                                buffer_copy_string_len(token, CONST_STR_LEN("(!)"));
                    117:                        }
                    118: 
                    119:                        break;
                    120:                case '&':
                    121:                        if (t->input[t->offset + 1] == '&') {
                    122:                                t->offset += 2;
                    123:                                t->line_pos += 2;
                    124: 
                    125:                                tid = TK_AND;
                    126: 
                    127:                                buffer_copy_string_len(token, CONST_STR_LEN("(&&)"));
                    128:                        } else {
                    129:                                log_error_write(srv, __FILE__, __LINE__, "sds",
                    130:                                                "pos:", t->line_pos,
                    131:                                                "missing second &");
                    132:                                return -1;
                    133:                        }
                    134: 
                    135:                        break;
                    136:                case '|':
                    137:                        if (t->input[t->offset + 1] == '|') {
                    138:                                t->offset += 2;
                    139:                                t->line_pos += 2;
                    140: 
                    141:                                tid = TK_OR;
                    142: 
                    143:                                buffer_copy_string_len(token, CONST_STR_LEN("(||)"));
                    144:                        } else {
                    145:                                log_error_write(srv, __FILE__, __LINE__, "sds",
                    146:                                                "pos:", t->line_pos,
                    147:                                                "missing second |");
                    148:                                return -1;
                    149:                        }
                    150: 
                    151:                        break;
                    152:                case '\t':
                    153:                case ' ':
                    154:                        t->offset++;
                    155:                        t->line_pos++;
                    156:                        break;
                    157: 
                    158:                case '\'':
                    159:                        /* search for the terminating " */
                    160:                        for (i = 1; t->input[t->offset + i] && t->input[t->offset + i] != '\'';  i++);
                    161: 
                    162:                        if (t->input[t->offset + i]) {
                    163:                                tid = TK_VALUE;
                    164: 
                    165:                                buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
                    166: 
                    167:                                t->offset += i + 1;
                    168:                                t->line_pos += i + 1;
                    169:                        } else {
                    170:                                /* ERROR */
                    171: 
                    172:                                log_error_write(srv, __FILE__, __LINE__, "sds",
                    173:                                                "pos:", t->line_pos,
                    174:                                                "missing closing quote");
                    175: 
                    176:                                return -1;
                    177:                        }
                    178: 
                    179:                        break;
                    180:                case '(':
                    181:                        t->offset++;
                    182:                        t->in_brace++;
                    183: 
                    184:                        tid = TK_LPARAN;
                    185: 
                    186:                        buffer_copy_string_len(token, CONST_STR_LEN("("));
                    187:                        break;
                    188:                case ')':
                    189:                        t->offset++;
                    190:                        t->in_brace--;
                    191: 
                    192:                        tid = TK_RPARAN;
                    193: 
                    194:                        buffer_copy_string_len(token, CONST_STR_LEN(")"));
                    195:                        break;
                    196:                case '$':
                    197:                        if (t->input[t->offset + 1] == '{') {
                    198:                                for (i = 2; t->input[t->offset + i] && t->input[t->offset + i] != '}';  i++);
                    199: 
                    200:                                if (t->input[t->offset + i] != '}') {
                    201:                                        log_error_write(srv, __FILE__, __LINE__, "sds",
                    202:                                                        "pos:", t->line_pos,
                    203:                                                        "missing closing quote");
                    204: 
                    205:                                        return -1;
                    206:                                }
                    207: 
                    208:                                buffer_copy_string_len(token, t->input + t->offset + 2, i-3);
                    209:                        } else {
                    210:                                for (i = 1; isalpha(t->input[t->offset + i]) || t->input[t->offset + i] == '_';  i++);
                    211: 
                    212:                                buffer_copy_string_len(token, t->input + t->offset + 1, i-1);
                    213:                        }
                    214: 
                    215:                        tid = TK_VALUE;
                    216: 
                    217:                        if (NULL != (ds = (data_string *)array_get_element(p->ssi_cgi_env, token->ptr))) {
                    218:                                buffer_copy_string_buffer(token, ds->value);
                    219:                        } else if (NULL != (ds = (data_string *)array_get_element(p->ssi_vars, token->ptr))) {
                    220:                                buffer_copy_string_buffer(token, ds->value);
                    221:                        } else {
                    222:                                buffer_copy_string_len(token, CONST_STR_LEN(""));
                    223:                        }
                    224: 
                    225:                        t->offset += i;
                    226:                        t->line_pos += i;
                    227: 
                    228:                        break;
                    229:                default:
                    230:                        for (i = 0; isgraph(t->input[t->offset + i]);  i++) {
                    231:                                char d = t->input[t->offset + i];
                    232:                                switch(d) {
                    233:                                case ' ':
                    234:                                case '\t':
                    235:                                case ')':
                    236:                                case '(':
                    237:                                case '\'':
                    238:                                case '=':
                    239:                                case '!':
                    240:                                case '<':
                    241:                                case '>':
                    242:                                case '&':
                    243:                                case '|':
                    244:                                        break;
                    245:                                }
                    246:                        }
                    247: 
                    248:                        tid = TK_VALUE;
                    249: 
                    250:                        buffer_copy_string_len(token, t->input + t->offset, i);
                    251: 
                    252:                        t->offset += i;
                    253:                        t->line_pos += i;
                    254: 
                    255:                        break;
                    256:                }
                    257:        }
                    258: 
                    259:        if (tid) {
                    260:                *token_id = tid;
                    261: 
                    262:                return 1;
                    263:        } else if (t->offset < t->size) {
                    264:                log_error_write(srv, __FILE__, __LINE__, "sds",
                    265:                                "pos:", t->line_pos,
                    266:                                "foobar");
                    267:        }
                    268:        return 0;
                    269: }
                    270: 
                    271: int ssi_eval_expr(server *srv, connection *con, plugin_data *p, const char *expr) {
                    272:        ssi_tokenizer_t t;
                    273:        void *pParser;
                    274:        int token_id;
                    275:        buffer *token;
                    276:        ssi_ctx_t context;
                    277:        int ret;
                    278: 
                    279:        t.input = expr;
                    280:        t.offset = 0;
                    281:        t.size = strlen(expr);
                    282:        t.line_pos = 1;
                    283: 
                    284:        t.in_key = 1;
                    285:        t.in_brace = 0;
                    286:        t.in_cond = 0;
                    287: 
                    288:        context.ok = 1;
                    289:        context.srv = srv;
                    290: 
                    291:        /* default context */
                    292: 
                    293:        pParser = ssiexprparserAlloc( malloc );
                    294:        token = buffer_init();
                    295:        while((1 == (ret = ssi_expr_tokenizer(srv, con, p, &t, &token_id, token))) && context.ok) {
                    296:                ssiexprparser(pParser, token_id, token, &context);
                    297: 
                    298:                token = buffer_init();
                    299:        }
                    300:        ssiexprparser(pParser, 0, token, &context);
                    301:        ssiexprparserFree(pParser, free );
                    302: 
                    303:        buffer_free(token);
                    304: 
                    305:        if (ret == -1) {
                    306:                log_error_write(srv, __FILE__, __LINE__, "s",
                    307:                                "expr parser failed");
                    308:                return -1;
                    309:        }
                    310: 
                    311:        if (context.ok == 0) {
                    312:                log_error_write(srv, __FILE__, __LINE__, "sds",
                    313:                                "pos:", t.line_pos,
                    314:                                "parser failed somehow near here");
                    315:                return -1;
                    316:        }
                    317: #if 0
                    318:        log_error_write(srv, __FILE__, __LINE__, "ssd",
                    319:                        "expr: ",
                    320:                        expr,
                    321:                        context.val.bo);
                    322: #endif
                    323:        return context.val.bo;
                    324: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>