Annotation of embedaddon/lighttpd/src/mod_ssi_expr.c, revision 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>