From 0532d20e4dee3cb0cb25f005124f379a36318b06 Mon Sep 17 00:00:00 2001 From: Nick Galbreath Date: Mon, 27 May 2013 18:04:04 +0400 Subject: [PATCH] update to 3.0.0-pre2 --- apache2/libinjection/libinjection.h | 28 +- apache2/libinjection/libinjection_sqli.c | 781 +-- apache2/libinjection/libinjection_sqli_data.h | 4702 +++++++++++++---- 3 files changed, 3993 insertions(+), 1518 deletions(-) diff --git a/apache2/libinjection/libinjection.h b/apache2/libinjection/libinjection.h index 38fd9810..497fb2fe 100644 --- a/apache2/libinjection/libinjection.h +++ b/apache2/libinjection/libinjection.h @@ -37,7 +37,7 @@ extern "C" { * See python's normalized version * http://www.python.org/dev/peps/pep-0386/#normalizedversion */ -#define LIBINJECTION_VERSION "2.0.0" +#define LIBINJECTION_VERSION "3.0.0-pre2" #define ST_MAX_SIZE 32 #define MAX_TOKENS 5 @@ -50,6 +50,7 @@ typedef struct { char type; char str_open; char str_close; + char var_count; char val[ST_MAX_SIZE]; } stoken_t; @@ -62,18 +63,12 @@ typedef struct { size_t pos; int in_comment; - /* syntax fixups state */ - stoken_t syntax_current; - stoken_t syntax_last; - stoken_t syntax_comment; - - /* constant folding state */ - stoken_t fold_current; - stoken_t fold_last; - int fold_state; - /* final sqli data */ - stoken_t tokenvec[MAX_TOKENS]; + stoken_t *current; + + /* MAX TOKENS + 1 since use one extra token to determine + the type of the previous token */ + stoken_t tokenvec[MAX_TOKENS + 1]; /* +1 for ending null */ char pat[MAX_TOKENS + 1]; @@ -130,6 +125,15 @@ int libinjection_is_string_sqli(sfilter * sql_state, const char delim, ptr_fingerprints_fn fn, void* callbackarg); +/* FOR H@CKERS ONLY + * + */ + +void libinjection_sqli_init(sfilter* sql_state, const char* str, + size_t slen, char delim); + +int libinjection_sqli_tokenize(sfilter * sql_state, stoken_t *ouput); + #ifdef __cplusplus } #endif diff --git a/apache2/libinjection/libinjection_sqli.c b/apache2/libinjection/libinjection_sqli.c index b2d26221..4067c223 100644 --- a/apache2/libinjection/libinjection_sqli.c +++ b/apache2/libinjection/libinjection_sqli.c @@ -23,7 +23,7 @@ #endif #if 0 -#define FOLD_DEBUG printf("%d: Fold state = %d, current=%c, last=%c\n", __LINE__, sf->fold_state, current->type, last->type == CHAR_NULL ? '~': last->type) +#define FOLD_DEBUG printf("%d \t more=%d pos=%d left=%d\n", __LINE__, more, (int)pos, (int)left); #else #define FOLD_DEBUG #endif @@ -93,6 +93,21 @@ strlenspn(const char *s, size_t len, const char *accept) return len; } +static size_t +strlencspn(const char *s, size_t len, const char *accept) +{ + size_t i; + for (i = 0; i < len; ++i) { + /* likely we can do better by inlining this function + * but this works for now + */ + if (strchr(accept, s[i]) != NULL) { + return i; + } + } + return len; +} + /* * ASCII half-case-insenstive compare! * @@ -253,11 +268,6 @@ static void st_clear(stoken_t * st) st->val[0] = CHAR_NULL; } -static int st_is_empty(const stoken_t * st) -{ - return st->type == CHAR_NULL; -} - static void st_assign_char(stoken_t * st, const char stype, const char value) { st->type = stype; @@ -297,28 +307,11 @@ static int st_is_unary_op(const stoken_t * st) strcmp(st->val, "~"))); } -static int st_is_arith_op(const stoken_t * st) -{ - return (st->type == 'o' && !(strcmp(st->val, "-") && - strcmp(st->val, "+") && - strcmp(st->val, "~") && - strcmp(st->val, "!") && - strcmp(st->val, "/") && - strcmp(st->val, "%") && - strcmp(st->val, "*") && - strcmp(st->val, "|") && - strcmp(st->val, "&") && - /* arg1 = upper case only, arg1 = mixed case */ - cstrcasecmp("MOD", st->val) && - cstrcasecmp("DIV", st->val))); -} - /* Parsers * * */ - static size_t parse_white(sfilter * sf) { return sf->pos + 1; @@ -326,37 +319,33 @@ static size_t parse_white(sfilter * sf) static size_t parse_operator1(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; size_t pos = sf->pos; - st_assign_char(current, 'o', cs[pos]); + st_assign_char(sf->current, 'o', cs[pos]); return pos + 1; } static size_t parse_other(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; size_t pos = sf->pos; - st_assign_char(current, '?', cs[pos]); + st_assign_char(sf->current, '?', cs[pos]); return pos + 1; } static size_t parse_char(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; size_t pos = sf->pos; - st_assign_char(current, cs[pos], cs[pos]); + st_assign_char(sf->current, cs[pos], cs[pos]); return pos + 1; } static size_t parse_eol_comment(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -364,17 +353,16 @@ static size_t parse_eol_comment(sfilter * sf) const char *endpos = (const char *) memchr((const void *) (cs + pos), '\n', slen - pos); if (endpos == NULL) { - st_assign(current, 'c', cs + pos, slen - pos); + st_assign(sf->current, 'c', cs + pos, slen - pos); return slen; } else { - st_assign(current, 'c', cs + pos, endpos - cs - pos); + st_assign(sf->current, 'c', cs + pos, endpos - cs - pos); return (endpos - cs) + 1; } } static size_t parse_dash(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -384,7 +372,7 @@ static size_t parse_dash(sfilter * sf) if (pos1 < slen && cs[pos1] == '-') { return parse_eol_comment(sf); } else { - st_assign_char(current, 'o', '-'); + st_assign_char(sf->current, 'o', '-'); return pos1; } } @@ -431,7 +419,6 @@ static size_t is_mysql_comment(const char *cs, const size_t len, size_t pos) static size_t parse_slash(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -454,7 +441,7 @@ static size_t parse_slash(sfilter * sf) /* * unterminated comment */ - st_assign(current, 'c', cs + pos, slen - pos); + st_assign(sf->current, 'c', cs + pos, slen - pos); return slen; } else { /* @@ -468,7 +455,7 @@ static size_t parse_slash(sfilter * sf) if (memchr2(cur + 2, ptr - (cur + 1), '/', '*') != NULL) { ctype = 'X'; } - st_assign(current, ctype, cs + pos, clen); + st_assign(sf->current, ctype, cs + pos, clen); return pos + clen; } @@ -477,14 +464,13 @@ static size_t parse_slash(sfilter * sf) * MySQL Comment */ sf->in_comment = TRUE; - st_clear(current); + st_clear(sf->current); return pos + inc; } } static size_t parse_backslash(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -493,7 +479,7 @@ static size_t parse_backslash(sfilter * sf) * Weird MySQL alias for NULL, "\N" (capital N only) */ if (pos + 1 < slen && cs[pos + 1] == 'N') { - st_assign(current, '1', "NULL", 4); + st_assign(sf->current, '1', "NULL", 4); return pos + 2; } else { return parse_other(sf); @@ -510,7 +496,6 @@ static int is_operator2(const char *key) static size_t parse_operator2(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -532,25 +517,29 @@ static size_t parse_operator2(sfilter * sf) */ if (sf->in_comment && op2[0] == '*' && op2[1] == '/') { sf->in_comment = FALSE; - st_clear(current); + st_clear(sf->current); return pos + 2; } else if (pos + 2 < slen && op2[0] == '<' && op2[1] == '=' && cs[pos + 2] == '>') { /* * special 3-char operator */ - st_assign(current, 'o', "<=>", 3); + st_assign(sf->current, 'o', "<=>", 3); return pos + 3; } else if (is_operator2(op2)) { if (streq(op2, "&&") || streq(op2, "||")) { - st_assign(current, '&', op2, 2); + st_assign(sf->current, '&', op2, 2); } else { /* * normal 2 char operator */ - st_assign(current, 'o', op2, 2); + st_assign(sf->current, 'o', op2, 2); } return pos + 2; + } else if (op2[0] == ':') { + /* ':' is not an operator */ + st_assign_char(sf->current, ':', ':'); + return pos + 1; } else { /* * must be a single char operator @@ -614,7 +603,6 @@ static size_t parse_string_core(const char *cs, const size_t len, size_t pos, */ static size_t parse_string(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -622,34 +610,93 @@ static size_t parse_string(sfilter * sf) /* * assert cs[pos] == single or double quote */ - return parse_string_core(cs, slen, pos, current, cs[pos], 1); + return parse_string_core(cs, slen, pos, sf->current, cs[pos], 1); +} + +/** Parse MySQL `backtick` quoted strings + * + * Unforunately, the escaping rules for `-quoted strings is different + * when finding a "`" you need to look at NEXT CHAR to see if it's "`" + * If so, you need to jump two characters ahead + * + * In normal strings, you need to look at PREVIOUS CHAR... and if so + * just jump ahead one char. + * + * Also we don't need to code to fake an opening "`" + * + * Tried to keep code as similar to parse_string_core. + */ +static size_t parse_string_tick(sfilter *sf) +{ + const size_t offset = 1; + const char delim = '`'; + + const char *cs = sf->s; + const size_t len = sf->slen; + size_t pos = sf->pos; + stoken_t *st = sf->current; + + /* + * len -pos -1 : offset is to skip the perhaps first quote char + */ + const char *qpos = + (const char *) memchr((const void *) (cs + pos + offset), delim, + len - pos - offset); + + st->str_open = delim; + + while (TRUE) { + if (qpos == NULL) { + /* + * string ended with no trailing quote + * assign what we have + */ + st_assign(st, 's', cs + pos + offset, len - pos - offset); + st->str_close = CHAR_NULL; + return len; + } else if (qpos + 1 == (cs + len) || ((qpos + 1) < (cs + len) && *(qpos + 1) != delim)) { + /* + * ending quote is not escaped.. copy and end + */ + st_assign(st, 's', cs + pos + offset, + qpos - (cs + pos + offset)); + st->str_close = delim; + return qpos - cs + 1; + } else { + /* + * we got a `` so advance by 2 chars + */ + qpos = + (const char *) memchr((const void *) (qpos + 2), delim, + (cs + len) - (qpos + 2)); + } + } } static size_t parse_word(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; size_t pos = sf->pos; char *dot; char ch; size_t slen = - strlenspn(cs + pos, sf->slen - pos, - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$."); + strlencspn(cs + pos, sf->slen - pos, + " .`<>:\\?=@!#~+-*/&|^%(),';\r\n\t\"\013\014"); - st_assign(current, 'n', cs + pos, slen); + st_assign(sf->current, 'n', cs + pos, slen); - dot = strchr(current->val, '.'); + dot = strchr(sf->current->val, '.'); if (dot != NULL) { *dot = '\0'; - ch = is_keyword(current->val); + ch = is_keyword(sf->current->val); - if (ch == 'k' || ch == 'o') { + if (ch == 'k' || ch == 'o' || ch == 'E') { /* * we got something like "SELECT.1" */ - current->type = ch; - return pos + strlen(current->val); + sf->current->type = ch; + return pos + strlen(sf->current->val); } else { /* * something else, put back dot @@ -663,46 +710,103 @@ static size_t parse_word(sfilter * sf) */ if (slen < ST_MAX_SIZE) { - ch = is_keyword(current->val); + ch = is_keyword(sf->current->val); if (ch == CHAR_NULL) { ch = 'n'; } - current->type = ch; + sf->current->type = ch; } return pos + slen; } +/* MySQL backticks are a cross between string and + * and a bare word. + * + */ +static size_t parse_tick(sfilter* sf) +{ + /* first we pretend we are looking for a string */ + size_t slen = parse_string_tick(sf); + + /* we could check to see if start and end of + * of string are both "`", i.e. make sure we have + * matching set. `foo` vs. `foo + * but I don't think it matters much + */ + + + /* check value of string to see if it's a keyword, + * function, operator, etc + */ + char ch = is_keyword(sf->current->val); + if (ch == 'f') { + /* if it's a function, then convert token */ + sf->current->type = 'f'; + } else { + /* otherwise it's a 'n' type -- mysql treats + * everything as a bare word + */ + sf->current->type = 'n'; + } + return slen; +} + static size_t parse_var(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; - size_t pos = sf->pos; - size_t pos1 = pos + 1; + size_t pos = sf->pos + 1; size_t xlen; + /* + * var_count is only used to reconstruct + * the input. It counts the number of '@' + * seen 0 in the case of NULL, 1 or 2 + */ + /* * move past optional other '@' */ - if (pos1 < slen && cs[pos1] == '@') { - pos1 += 1; + if (pos < slen && cs[pos] == '@') { + pos += 1; + sf->current->var_count = 2; + } else { + sf->current->var_count = 1; } - xlen = strlenspn(cs + pos1, slen - pos1, - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); + /* + * MySQL allows @@`version` + */ + if (pos < slen) { + if (cs[pos] == '`') { + sf->pos = pos; + pos = parse_string_tick(sf); + sf->current->type = 'v'; + return pos; + } else if (cs[pos] == CHAR_SINGLE || cs[pos] == CHAR_DOUBLE) { + sf->pos = pos; + pos = parse_string(sf); + sf->current->type = 'v'; + return pos; + } + } + + + xlen = strlencspn(cs + pos, slen - pos, + " <>:\\?=@!#~+-*/&|^%(),';\r\n\t\"\013\014"); +// "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$"); if (xlen == 0) { - st_assign(current, 'v', cs + pos, (pos1 - pos)); - return pos1; + st_assign(sf->current, 'v', cs + pos, 0); + return pos; } else { - st_assign(current, 'v', cs + pos, xlen + (pos1 - pos)); - return pos1 + xlen; + st_assign(sf->current, 'v', cs + pos, xlen); + return pos + xlen; } } static size_t parse_money(sfilter *sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -719,14 +823,13 @@ static size_t parse_money(sfilter *sf) */ return pos + 1; } else { - st_assign(current, '1', cs + pos, 1 + xlen); + st_assign(sf->current, '1', cs + pos, 1 + xlen); return pos + 1 + xlen; } } static size_t parse_number(sfilter * sf) { - stoken_t *current = &sf->syntax_current; const char *cs = sf->s; const size_t slen = sf->slen; size_t pos = sf->pos; @@ -740,10 +843,10 @@ static size_t parse_number(sfilter * sf) xlen = strlenspn(cs + pos + 2, slen - pos - 2, "0123456789ABCDEFabcdef"); if (xlen == 0) { - st_assign(current, 'n', "0X", 2); + st_assign(sf->current, 'n', "0X", 2); return pos + 2; } else { - st_assign(current, '1', cs + pos, 2 + xlen); + st_assign(sf->current, '1', cs + pos, 2 + xlen); return pos + 2 + xlen; } } @@ -758,7 +861,7 @@ static size_t parse_number(sfilter * sf) pos += 1; } if (pos - start == 1) { - st_assign_char(current, 'n', '.'); + st_assign_char(sf->current, 'n', '.'); return pos; } } @@ -779,24 +882,24 @@ static size_t parse_number(sfilter * sf) * the number part and leave the rest to be * parsed later */ - st_assign(current, '1', cs + start, pos - start); + st_assign(sf->current, '1', cs + start, pos - start); return pos; } } - st_assign(current, '1', cs + start, pos - start); + st_assign(sf->current, '1', cs + start, pos - start); return pos; } -int parse_token(sfilter * sf) +int libinjection_sqli_tokenize(sfilter * sf, stoken_t *current) { - stoken_t *current = &sf->syntax_current; const char *s = sf->s; const size_t slen = sf->slen; size_t *pos = &sf->pos; pt2Function fnptr; st_clear(current); + sf->current = current; /* * if we are at beginning of string @@ -812,17 +915,16 @@ int parse_token(sfilter * sf) /* * get current character */ - const int ch = (int) (s[*pos]); + const unsigned ch = (unsigned int) (s[*pos]); /* * if not ascii, then continue... * actually probably need to just assuming * it's a string */ - if (ch < 0 || ch > 127) { - *pos += 1; - continue; - } + if (ch > 127) { + fnptr = parse_word; + } else { /* * look up the parser, and call it @@ -831,6 +933,7 @@ int parse_token(sfilter * sf) * charparsers[ch]() */ fnptr = char_parse_map[ch]; + } *pos = (*fnptr) (sf); /* @@ -845,13 +948,14 @@ int parse_token(sfilter * sf) /** * Initializes parsing state - * TBD: explicity add parsing content (NULL, SINGLE, DOUBLE) + * */ -void sfilter_reset(sfilter * sf, const char *s, size_t len) +void libinjection_sqli_init(sfilter * sf, const char *s, size_t len, char delim) { memset(sf, 0, sizeof(sfilter)); sf->s = s; sf->slen = len; + sf->delim = delim; } /** See if two tokens can be merged since they are compound SQL phrases. @@ -880,7 +984,11 @@ static int syntax_merge_words(stoken_t * a, stoken_t * b) if (! (a->type == 'k' || a->type == 'n' || a->type == 'o' - || a->type == 'U')) { + || a->type == 'U' || a->type == 'E')) { + return FALSE; + } + + if (! st_is_multiword_start(a)) { return FALSE; } @@ -907,275 +1015,213 @@ static int syntax_merge_words(stoken_t * a, stoken_t * b) } } -/* This does some simple syntax cleanup based on the token - * - * - */ -int sqli_tokenize(sfilter * sf, stoken_t * sout) -{ - stoken_t *last = &sf->syntax_last; - stoken_t *current = &sf->syntax_current; - - while (parse_token(sf)) { - char ttype = current->type; - - /* - * TBD: hmm forgot logic here. - */ - if (ttype == 'c') { - st_copy(&sf->syntax_comment, current); - continue; - } - st_clear(&sf->syntax_comment); - - /* - * If we don't have a saved token, and we have - * a string: save it. if the next token is also a string - * then merge them. e.g. "A" "B" in SQL is actually "AB" - * a n/k/U/o type: save since next token my be merged together - * for example: "LEFT" + "JOIN" = "LEFT JOIN" - * a o/& type: TBD need to review. - * - */ - if (last->type == CHAR_NULL) { - switch (ttype) { - - /* - * items that have special needs - */ - case 's': - st_copy(last, current); - continue; - case 'n': - case 'k': - case 'U': - case '&': - case 'o': - if (st_is_multiword_start(current)) { - st_copy(last, current); - continue; - } else if (current->type == 'o' || current->type == '&') { - /* } else if (st_is_unary_op(current)) { */ - st_copy(last, current); - continue; - } else { - /* - * copy to out - */ - st_copy(sout, current); - return TRUE; - } - default: - /* - * copy to out - */ - st_copy(sout, current); - return TRUE; - } - } - /* - * We have a saved token - */ - - switch (ttype) { - case 's': - if (last->type == 's') { - /* - * "FOO" "BAR" == "FOO" (skip second string) - */ - continue; - } else { - st_copy(sout, last); - st_copy(last, current); - return TRUE; - } - break; - - case 'o': - /* - * first case to handle "IS" + "NOT" - */ - if (syntax_merge_words(last, current)) { - continue; - } else if (st_is_unary_op(current) - && (last->type == 'o' || last->type == '&' - || last->type == 'U')) { - /* - * if an operator is followed by a unary operator, skip it. - * 1, + ==> "+" is not unary, it's arithmetic - * AND, + ==> "+" is unary - */ - continue; - } else { - /* - * no match - */ - st_copy(sout, last); - st_copy(last, current); - return TRUE; - } - break; - - case 'n': - case 'k': - if (syntax_merge_words(last, current)) { - continue; - } else { - /* - * total no match - */ - st_copy(sout, last); - st_copy(last, current); - return TRUE; - } - break; - - default: - /* - * fix up for ambigous "IN" - * handle case where IN is typically a function - * but used in compound "IN BOOLEAN MODE" jive - * - * warning on cstrcasecmp arg0=upper case only, arg1 = mixed - */ - if (last->type == 'n' && !cstrcasecmp("IN", last->val)) { - st_copy(last, current); - st_assign(sout, 'f', "IN", 2); - return TRUE; - } else { - /* - * no match at all - */ - st_copy(sout, last); - st_copy(last, current); - return TRUE; - } - break; - } - } - - /* - * final cleanup - */ - if (last->type) { - st_copy(sout, last); - st_clear(last); - return TRUE; - } else if (sf->syntax_comment.type) { - /* - * TBD - */ - st_copy(sout, &sf->syntax_comment); - st_clear(&sf->syntax_comment); - return TRUE; - } else { - return FALSE; - } -} /* * My apologies, this code is a mess */ -int filter_fold(sfilter * sf, stoken_t * sout) +int filter_fold(sfilter * sf) { - stoken_t *last = &sf->fold_last; - stoken_t *current = &sf->fold_current; + stoken_t last_comment; - if (sf->fold_state == 4 && !st_is_empty(last)) { - st_copy(sout, last); - sf->fold_state = 2; - st_clear(last); - return FALSE; - } + stoken_t * current; - while (sqli_tokenize(sf, current)) { - /* - * 0 = start of statement - * skip ( and unary ops - */ - if (sf->fold_state == 0) { - if (current->type == '(') { - continue; - } - if (st_is_unary_op(current)) { - continue; - } - sf->fold_state = 1; - } + /* POS is the positive of where the NEXT token goes */ + size_t pos = 0; - if (st_is_empty(last)) { - FOLD_DEBUG; - if (current->type == '1' || current->type == 'n' - || current->type == '(') { - sf->fold_state = 2; - st_copy(last, current); - } - st_copy(sout, current); - return FALSE; - } else if (last->type == '(' && st_is_unary_op(current)) { - /* - * similar to beginning of statement - * an opening '(' resets state, and we should skip all - * unary operators - */ - continue; - } else if (last->type == '(' && current->type == '(') { - /* if we get another '(' after another - * emit 1, but keep state - */ - st_copy(sout, current); - return FALSE; - } else if ((last->type == '1' || last->type == 'n') - && st_is_arith_op(current)) { - FOLD_DEBUG; - st_copy(last, current); - } else if (last->type == 'o' - && (current->type == '1' || current->type == 'n')) { - FOLD_DEBUG; - st_copy(last, current); - } else { - if (sf->fold_state == 2) { - if (last->type != '1' && last->type != '(' - && last->type != 'n') { - FOLD_DEBUG; - st_copy(sout, last); - st_copy(last, current); - sf->fold_state = 4; - } else { - FOLD_DEBUG; - st_copy(sout, current); - st_clear(last); - } - return FALSE; - } else { - if (last->type == 'o') { - st_copy(sout, last); - st_copy(last, current); - sf->fold_state = 4; - } else { - sf->fold_state = 2; - st_copy(sout, current); - st_clear(last); - } - return FALSE; - } - } - } + /* LEFT is a count of how many tokens that are already + folded or processed (i.e. part of the fingerprint) */ + size_t left = 0; - if (!st_is_empty(last)) { - if (st_is_arith_op(last)) { - st_copy(sout, last); - st_clear(last); - return FALSE; - } else { - st_clear(last); - } - } + int more = 1; - /* - * all done: nothing more to parse + st_clear(&last_comment); + + /* Skip all initial comments, right-parens ( and unary operators + * */ - return TRUE; + current = &(sf->tokenvec[0]); + while (more) { + more = libinjection_sqli_tokenize(sf, current); + if ( ! (current->type == 'c' || current->type == '(' || st_is_unary_op(current))) { + break; + } + } + + if (! more) { + /* If input was only comments, unary or (, then exit */ + return 0; + } else { + /* it's some other token */ + pos += 1; + } + + while (1) { + FOLD_DEBUG + /* get up to two tokens */ + while (more && pos <= MAX_TOKENS && (pos - left) < 2) { + current = &(sf->tokenvec[pos]); + more = libinjection_sqli_tokenize(sf, current); + if (more) { + if (current->type == 'c') { + st_copy(&last_comment, current); + } else { + last_comment.type = CHAR_NULL; + pos += 1; + } + } + } + FOLD_DEBUG + /* did we get 2 tokens? if not then we are done */ + if (pos - left != 2) { + left = pos; + break; + } + + /* FOLD: "ss" -> "s" + * "foo" "bar" is valid SQL + * just ignore second string + */ + if (sf->tokenvec[left].type == 's' && sf->tokenvec[left+1].type == 's') { + pos -= 1; + continue; + } else if (sf->tokenvec[left].type =='o' && st_is_unary_op(&sf->tokenvec[left+1])) { + pos -= 1; + if (left > 0) { + left -= 1; + } + continue; + } else if (sf->tokenvec[left].type =='(' && st_is_unary_op(&sf->tokenvec[left+1])) { + pos -= 1; + if (left > 0) { + left -= 1; + } + continue; + } else if (syntax_merge_words(&sf->tokenvec[left], &sf->tokenvec[left+1])) { + pos -= 1; + continue; + } else if (sf->tokenvec[left].type == 'n' && + sf->tokenvec[left+1].type == '(' && ( + cstrcasecmp("IN", sf->tokenvec[left].val) == 0 || + cstrcasecmp("DATABASE", sf->tokenvec[left].val) == 0 || + cstrcasecmp("USER", sf->tokenvec[left].val) == 0 || + cstrcasecmp("PASSWORD", sf->tokenvec[left].val) == 0 + ) + ) { + + // pos is the same + // other conversions need to go here... for instance + // password CAN be a function, coalese CAN be a function + sf->tokenvec[left].type = 'f'; + continue; +#if 0 + } else if (sf->tokenvec[left].type == 'o' && cstrcasecmp("LIKE", sf->tokenvec[left].val) == 0 + && sf->tokenvec[left+1].type == '(') { + // two use cases "foo" LIKE "BAR" (normal operator) + // "foo" = LIKE(1,2) + sf->tokenvec[left].type = 'f'; + continue; +#endif + } + + /* all cases of handing 2 tokens is done + and nothing matched. Get one more token + */ + FOLD_DEBUG + while (more && pos <= MAX_TOKENS && pos - left < 3) { + current = &(sf->tokenvec[pos]); + more = libinjection_sqli_tokenize(sf, current); + if (more) { + if (current->type == 'c') { + st_copy(&last_comment, current); + } else { + last_comment.type = CHAR_NULL; + pos += 1; + } + } + } + + /* do we have three tokens? If not then we are done */ + if (pos -left != 3) { + left = pos; + break; + } + + /* + * now look for three token folding + */ + if (sf->tokenvec[left].type == '1' && + sf->tokenvec[left+1].type == 'o' && + sf->tokenvec[left+2].type == '1') { + pos -= 2; + continue; + } else if (sf->tokenvec[left].type == 'o' && + sf->tokenvec[left+1].type != '(' && + sf->tokenvec[left+2].type == 'o') { + if (left > 0) { + left -= 1; + } + pos -= 2; + continue; + } else if (sf->tokenvec[left].type == '&' && + sf->tokenvec[left+2].type == '&') { + pos -= 2; + continue; + } else if ((sf->tokenvec[left].type == 'n' || sf->tokenvec[left].type == '1' ) && + sf->tokenvec[left+1].type == 'o' && + (sf->tokenvec[left+2].type == '1' || sf->tokenvec[left+2].type == 'n')) { + pos -= 2; + continue; +#if 0 + } else if ((sf->tokenvec[left].type == 'n' || sf->tokenvec[left].type == '1') && + sf->tokenvec[left+1].type == ',' && + (sf->tokenvec[left+2].type == '1' || sf->tokenvec[left+2].type == 'n')) { + pos -= 2; + continue; +#endif + } else if ((sf->tokenvec[left].type == 'k' || sf->tokenvec[left].type == 'E') && + st_is_unary_op(&sf->tokenvec[left+1]) && + (sf->tokenvec[left+2].type == '1' || sf->tokenvec[left+2].type == 'n' || sf->tokenvec[left+2].type == 'v' || sf->tokenvec[left+2].type == 's' || sf->tokenvec[left+2].type == 'f' )) { + // remove unary operators + // select - 1 + st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); + pos -= 1; + } else if (sf->tokenvec[left].type == 'n' && + sf->tokenvec[left+1].type == 'n' && sf->tokenvec[left+1].val[0] == '.' && + sf->tokenvec[left+2].type == 'n') { + /* ignore the '.n' + * typically is this dabasename.table + */ + pos -= 2; + continue; + } + + + /* no folding -- assume left-most token is + is good, now use the existing 2 tokens -- + do not get another + */ + + left += 1; + + } /* while(1) */ + + /* if we have 4 or less tokens, and we had a comment token + * at the end, add it back + */ + + if (left < MAX_TOKENS && last_comment.type == 'c') { + st_copy(&sf->tokenvec[left], &last_comment); + left += 1; + } + + /* sometimes we grab a 6th token to help + determine the type of token 5. + */ + if (left > MAX_TOKENS) { + left = MAX_TOKENS; + } + + return (int)left; } /* secondary api: detects SQLi in a string, GIVEN a context. @@ -1193,22 +1239,16 @@ int libinjection_is_string_sqli(sfilter * sql_state, const char delim, ptr_fingerprints_fn fn, void* callbackarg) { + int i; int tlen = 0; char ch; int patmatch; - int all_done; - sfilter_reset(sql_state, s, slen); - sql_state->delim = delim; + libinjection_sqli_init(sql_state, s, slen, delim); - while (tlen < MAX_TOKENS) { - all_done = filter_fold(sql_state, &(sql_state->tokenvec[tlen])); - if (all_done) { - break; - } - - sql_state->pat[tlen] = sql_state->tokenvec[tlen].type; - tlen += 1; + tlen = filter_fold(sql_state); + for (i = 0; i < tlen; ++i) { + sql_state->pat[i] = sql_state->tokenvec[i].type; } /* @@ -1350,7 +1390,8 @@ int libinjection_is_string_sqli(sfilter * sql_state, if (streq(sql_state->pat, "sos") || streq(sql_state->pat, "s&s")) { if ((sql_state->tokenvec[0].str_open == CHAR_NULL) - && (sql_state->tokenvec[2].str_close == CHAR_NULL)) { + && (sql_state->tokenvec[2].str_close == CHAR_NULL) + && (sql_state->tokenvec[0].str_close == sql_state->tokenvec[2].str_open)) { /* * if ....foo" + "bar.... */ @@ -1362,25 +1403,21 @@ int libinjection_is_string_sqli(sfilter * sql_state, sql_state->reason = __LINE__; return FALSE; } - break; - } - } /* case 3 */ - case 5: { - if (streq(sql_state->pat, "sosos")) { - if (sql_state->tokenvec[0].str_open == CHAR_NULL) { - /* - * if ....foo" + "bar.... - */ - return TRUE; - } else { - /* - * not sqli - */ + } else if (streq(sql_state->pat, "so1")) { + if (sql_state->tokenvec[0].str_open != CHAR_NULL) { + /* "foo" -1 is ok, foo"-1 is not */ sql_state->reason = __LINE__; return FALSE; } - break; + } else if ((sql_state->tokenvec[1].type == 'k') && cstrcasecmp("INTO OUTFILE", sql_state->tokenvec[1].val)) { + sql_state->reason = __LINE__; + return FALSE; } + break; + } /* case 3 */ + case 5: { + /* nothing right now */ + break; } /* case 5 */ } /* end switch */ diff --git a/apache2/libinjection/libinjection_sqli_data.h b/apache2/libinjection/libinjection_sqli_data.h index bd0abd2b..1fcea59b 100644 --- a/apache2/libinjection/libinjection_sqli_data.h +++ b/apache2/libinjection/libinjection_sqli_data.h @@ -23,6 +23,7 @@ static size_t parse_string(sfilter *sf); static size_t parse_word(sfilter * sf); static size_t parse_var(sfilter * sf); static size_t parse_number(sfilter * sf); +static size_t parse_tick(sfilter * sf); static const char* operators2[] = { @@ -84,7 +85,7 @@ static const keyword_t sql_keywords[] = { {"ARRAY_TO_JSON", 'f'}, {"ARRAY_TO_STRING", 'f'}, {"ARRAY_UPPER", 'f'}, - {"AS", 'k'}, + {"AS", 'n'}, {"ASC", 'k'}, {"ASCII", 'f'}, {"ASENSITIVE", 'k'}, @@ -96,7 +97,7 @@ static const keyword_t sql_keywords[] = { {"AUTOINCREMENT", 'k'}, {"AVG", 'f'}, {"BEFORE", 'k'}, - {"BEGIN", 'k'}, + {"BEGIN", 'E'}, {"BENCHMARK", 'f'}, {"BETWEEN", 'k'}, {"BIGINT", 'k'}, @@ -121,7 +122,7 @@ static const keyword_t sql_keywords[] = { {"BY", 'n'}, {"CALL", 'k'}, {"CASCADE", 'k'}, - {"CASE", 'o'}, + {"CASE", 'E'}, {"CAST", 'f'}, {"CBOOL", 'f'}, {"CBRT", 'f'}, @@ -179,7 +180,7 @@ static const keyword_t sql_keywords[] = { {"COUNT", 'f'}, {"COUNT_BIG", 'k'}, {"CRC32", 'f'}, - {"CREATE", 'k'}, + {"CREATE", 'E'}, {"CROSS", 'n'}, {"CSNG", 'f'}, {"CTXSYS.DRITHSX.SN", 'f'}, @@ -201,7 +202,7 @@ static const keyword_t sql_keywords[] = { {"CURSOR_STATUS", 'f'}, {"CURTIME", 'f'}, {"CVAR", 'f'}, - {"DATABASE", 'k'}, + {"DATABASE", 'n'}, {"DATABASEPROPERTYEX", 'f'}, {"DATABASES", 'k'}, {"DATABASE_PRINCIPAL_ID", 'f'}, @@ -232,13 +233,14 @@ static const keyword_t sql_keywords[] = { {"DAY_MICROSECOND", 'k'}, {"DAY_MINUTE", 'k'}, {"DAY_SECOND", 'k'}, + {"DBMS_LOCK.SLEEP", 'f'}, {"DBMS_PIPE.RECEIVE_MESSAGE", 'f'}, {"DB_ID", 'f'}, {"DB_NAME", 'f'}, {"DCOUNT", 'f'}, {"DEC", 'k'}, {"DECIMAL", 'k'}, - {"DECLARE", 'k'}, + {"DECLARE", 'E'}, {"DECODE", 'f'}, {"DECRYPTBYASMKEY", 'f'}, {"DECRYPTBYCERT", 'f'}, @@ -265,7 +267,7 @@ static const keyword_t sql_keywords[] = { {"DLOOKUP", 'f'}, {"DMAX", 'f'}, {"DMIN", 'f'}, - {"DROP", 'k'}, + {"DROP", 'E'}, {"DSUM", 'f'}, {"DUAL", 'k'}, {"EACH", 'k'}, @@ -285,7 +287,7 @@ static const keyword_t sql_keywords[] = { {"EOMONTH", 'f'}, {"ESCAPED", 'k'}, {"EVENTDATA", 'f'}, - {"EXEC", 'k'}, + {"EXEC", 'E'}, {"EXECUTE", 'k'}, {"EXISTS", 'k'}, {"EXIT", 'k'}, @@ -352,7 +354,7 @@ static const keyword_t sql_keywords[] = { {"IDENT_CURRENT", 'f'}, {"IDENT_INCR", 'f'}, {"IDENT_SEED", 'f'}, - {"IF", 'k'}, + {"IF", 'E'}, {"IFF", 'f'}, {"IFNULL", 'f'}, {"IGNORE", 'k'}, @@ -369,7 +371,7 @@ static const keyword_t sql_keywords[] = { {"INNER", 'k'}, {"INOUT", 'k'}, {"INSENSITIVE", 'k'}, - {"INSERT", 'k'}, + {"INSERT", 'E'}, {"INSTR", 'f'}, {"INSTRREV", 'f'}, {"INT", 'k'}, @@ -476,7 +478,7 @@ static const keyword_t sql_keywords[] = { {"NO_WRITE_TO_BINLOG", 'k'}, {"NTH_VALUE", 'f'}, {"NTILE", 'f'}, - {"NULL", '1'}, + {"NULL", 'v'}, {"NULLIF", 'f'}, {"NUMERIC", 'k'}, {"NZ", 'f'}, @@ -512,7 +514,7 @@ static const keyword_t sql_keywords[] = { {"OWN3D", 'k'}, {"PARSENAME", 'f'}, {"PARTITION", 'k'}, - {"PASSWORD", 'k'}, + {"PASSWORD", 'n'}, {"PATHINDEX", 'f'}, {"PATINDEX", 'f'}, {"PERCENTILE_COUNT", 'f'}, @@ -607,11 +609,11 @@ static const keyword_t sql_keywords[] = { {"SCOPE_IDENTITY", 'f'}, {"SECOND_MICROSECOND", 'k'}, {"SEC_TO_TIME", 'f'}, - {"SELECT", 'k'}, + {"SELECT", 'E'}, {"SENSITIVE", 'k'}, {"SEPARATOR", 'k'}, {"SESSION_USER", 'f'}, - {"SET", 'k'}, + {"SET", 'E'}, {"SETATTR", 'f'}, {"SETSEED", 'f'}, {"SETVAL", 'f'}, @@ -623,7 +625,7 @@ static const keyword_t sql_keywords[] = { {"SHA1", 'f'}, {"SHA2", 'f'}, {"SHOW", 'n'}, - {"SHUTDOWN", 'k'}, + {"SHUTDOWN", 'E'}, {"SIGN", 'f'}, {"SIGNAL", 'k'}, {"SIGNBYASMKEY", 'f'}, @@ -690,6 +692,7 @@ static const keyword_t sql_keywords[] = { {"TAN", 'f'}, {"TERMINATED", 'k'}, {"TERTIARY_WEIGHTS", 'f'}, + {"TEXTPOS", 'f'}, {"TEXTPTR", 'f'}, {"TEXTVALID", 'f'}, {"THEN", 'k'}, @@ -748,14 +751,15 @@ static const keyword_t sql_keywords[] = { {"UNLOCK", 'k'}, {"UNNEST", 'f'}, {"UNSIGNED", 'k'}, - {"UPDATE", 'k'}, + {"UPDATE", 'E'}, {"UPDATEXML", 'f'}, {"UPPER", 'f'}, {"UPPER_INC", 'f'}, {"UPPER_INF", 'f'}, {"USAGE", 'k'}, - {"USE", 'k'}, + {"USE", 'E'}, {"USER_ID", 'n'}, + {"USER_LOCK.SLEEP", 'f'}, {"USER_NAME", 'f'}, {"USING", 'f'}, {"UTC_DATE", 'k'}, @@ -777,14 +781,14 @@ static const keyword_t sql_keywords[] = { {"VERIFYSIGNEDBYASMKEY", 'f'}, {"VERIFYSIGNEDBYCERT", 'f'}, {"VERSION", 'f'}, - {"WAITFOR", 'k'}, + {"WAITFOR", 'n'}, {"WEEK", 'f'}, {"WEEKDAY", 'f'}, {"WEEKDAYNAME", 'f'}, {"WEEKOFYEAR", 'f'}, {"WHEN", 'k'}, {"WHERE", 'k'}, - {"WHILE", 'k'}, + {"WHILE", 'E'}, {"WIDTH_BUCKET", 'f'}, {"WITH", 'k'}, {"XMLAGG", 'f'}, @@ -808,17 +812,20 @@ static const keyword_t sql_keywords[] = { {"ZEROBLOB", 'f'}, {"ZEROFILL", 'k'}, }; -static const size_t sql_keywords_sz = 752; +static const size_t sql_keywords_sz = 755; static const char* multikeywords_start[] = { "ALTER", "AT", "AT TIME", + "CREATE", + "CREATE OR", "CROSS", "FULL", "GROUP", "IN", "IN BOOLEAN", "INTERSECT", + "INTO", "IS", "IS DISTINCT", "IS NOT", @@ -837,19 +844,22 @@ static const char* multikeywords_start[] = { "SIMILAR", "SOUNDS", "UNION", + "WAITFOR", }; -static const size_t multikeywords_start_sz = 27; +static const size_t multikeywords_start_sz = 31; static const keyword_t multikeywords[] = { {"ALTER DOMAIN", 'k'}, {"ALTER TABLE", 'k'}, {"AT TIME", 'n'}, {"AT TIME ZONE", 'k'}, + {"CREATE OR REPLACE", 'E'}, {"CROSS JOIN", 'k'}, {"FULL OUTER", 'k'}, {"GROUP BY", 'B'}, {"IN BOOLEAN", 'n'}, {"IN BOOLEAN MODE", 'k'}, {"INTERSECT ALL", 'o'}, + {"INTO OUTFILE", 'k'}, {"IS DISTINCT", 'n'}, {"IS DISTINCT FROM", 'k'}, {"IS NOT", 'o'}, @@ -879,12 +889,15 @@ static const keyword_t multikeywords[] = { {"READ WRITE", 'k'}, {"RIGHT JOIN", 'k'}, {"RIGHT OUTER", 'k'}, - {"SELECT ALL", 'k'}, + {"SELECT ALL", 'E'}, {"SIMILAR TO", 'o'}, {"SOUNDS LIKE", 'o'}, {"UNION ALL", 'U'}, + {"WAITFOR DELAY", 'E'}, + {"WAITFOR RECEIVE", 'E'}, + {"WAITFOR TIME", 'E'}, }; -static const size_t multikeywords_sz = 43; +static const size_t multikeywords_sz = 48; typedef size_t (*pt2Function)(sfilter *sf); static const pt2Function char_parse_map[] = { @@ -946,7 +959,7 @@ static const pt2Function char_parse_map[] = { &parse_number, /* 55 */ &parse_number, /* 56 */ &parse_number, /* 57 */ - &parse_char, /* 58 */ + &parse_operator2, /* 58 */ &parse_char, /* 59 */ &parse_operator2, /* 60 */ &parse_operator2, /* 61 */ @@ -984,7 +997,7 @@ static const pt2Function char_parse_map[] = { &parse_other, /* 93 */ &parse_operator1, /* 94 */ &parse_word, /* 95 */ - &parse_word, /* 96 */ + &parse_tick, /* 96 */ &parse_word, /* 97 */ &parse_word, /* 98 */ &parse_word, /* 99 */ @@ -1019,35 +1032,86 @@ static const pt2Function char_parse_map[] = { }; static const char* sql_fingerprints[] = { - "&1o1U", - "&1osU", - "&1ovU", + "&1UE1", + "&1UEf", + "&1UEs", + "&1UEv", + "&1of(", + "&1os1", + "&1osf", + "&1oso", + "&1osv", + "&1ovf", + "&1ovo", + "&1ovs", + "&f(((", + "&f(()", + "&f((1", + "&f((f", + "&f((s", + "&f((v", + "&f())", "&f()o", "&f(1)", "&f(1o", + "&f(f(", "&f(s)", + "&f(so", "&f(v)", "&f(vo", - "&so1U", - "&sosU", - "&sovU", - "&vo1U", - "&vosU", - "&vovU", + "&sUE1", + "&sUEf", + "&sUEs", + "&sUEv", + "&so1f", + "&so1o", + "&so1s", + "&so1v", + "&sof(", + "&son1", + "&sonf", + "&sos1", + "&sosf", + "&soso", + "&sosv", + "&sovf", + "&sovo", + "&sovs", + "&vUE1", + "&vUEf", + "&vUEs", + "&vUEv", + "&vo1f", + "&vo1o", + "&vo1s", + "&vo1v", + "&vof(", + "&von1", + "&vonf", + "&vos1", + "&vosf", + "&voso", + "&vosv", + "&vovf", + "&vovo", + "&vovs", + "1&(((", + "1&((1", + "1&((E", "1&((f", - "1&((k", + "1&((s", + "1&((v", "1&(1)", "1&(1,", "1&(1o", + "1&(E1", + "1&(Ef", + "1&(Ek", + "1&(En", + "1&(Eo", + "1&(Es", + "1&(Ev", "1&(f(", - "1&(k(", - "1&(k1", - "1&(kf", - "1&(kk", - "1&(kn", - "1&(ko", - "1&(ks", - "1&(kv", "1&(s)", "1&(s,", "1&(so", @@ -1055,142 +1119,261 @@ static const char* sql_fingerprints[] = { "1&(v,", "1&(vo", "1&1", + "1&1&(", + "1&1&1", + "1&1&f", + "1&1&n", + "1&1&s", + "1&1&v", + "1&1B1", "1&1Bf", - "1&1Uk", + "1&1Bs", + "1&1Bv", + "1&1En", + "1&1U", + "1&1U(", + "1&1UE", + "1&1Uc", "1&1c", "1&1f(", + "1&1k1", + "1&1kf", + "1&1ks", + "1&1kv", "1&1o(", - "1&1o1", + "1&1oE", "1&1of", - "1&1ok", - "1&1on", "1&1oo", "1&1os", "1&1ov", + "1&1so", + "1&1vo", + "1&E((", + "1&E(1", + "1&E(f", + "1&E(o", + "1&E(s", + "1&E(v", + "1&E1k", + "1&E1o", + "1&Ef(", + "1&Ek1", + "1&Ekf", + "1&Eks", + "1&Ekv", + "1&Esk", + "1&Eso", + "1&Evk", + "1&Evo", "1&f((", "1&f()", "1&f(1", "1&f(f", - "1&f(k", "1&f(n", "1&f(s", "1&f(v", - "1&k(1", - "1&k(f", - "1&k(s", - "1&k(v", - "1&k1k", - "1&kUk", - "1&kk1", - "1&kks", - "1&kkv", - "1&ksk", - "1&kvk", - "1&n()", - "1&no1", + "1&k&1", + "1&k&f", + "1&k&s", + "1&k&v", + "1&k1o", + "1&kf(", + "1&knk", + "1&ko(", + "1&ko1", + "1&kof", + "1&kok", + "1&kon", + "1&kos", + "1&kov", + "1&kso", + "1&kvo", + "1&n&1", + "1&n&f", + "1&n&n", + "1&n&s", + "1&n&v", + "1&nc", + "1&nk1", + "1&nkf", + "1&nks", + "1&nkv", + "1&nof", "1&nos", "1&nov", + "1&o((", "1&o(1", + "1&o(f", "1&o(s", "1&o(v", + "1&o1", + "1&o1c", "1&o1o", + "1&of(", + "1&oko", + "1&os", + "1&osc", "1&oso", + "1&ov", + "1&ovc", "1&ovo", + "1&s", + "1&s&(", + "1&s&1", + "1&s&f", + "1&s&n", + "1&s&s", + "1&s&v", + "1&s1o", + "1&sB1", "1&sBf", + "1&sBs", + "1&sBv", + "1&sEn", + "1&sU", "1&sU(", - "1&sUk", + "1&sUE", + "1&sUc", + "1&sc", "1&sf(", + "1&sk1", + "1&skf", + "1&sks", + "1&skv", "1&so(", "1&so1", + "1&soE", "1&sof", - "1&sok", "1&son", "1&soo", "1&sos", "1&sov", + "1&svo", "1&v", + "1&v&(", + "1&v&1", + "1&v&f", + "1&v&n", + "1&v&s", + "1&v&v", + "1&vB1", "1&vBf", + "1&vBs", + "1&vBv", + "1&vEn", + "1&vU", "1&vU(", - "1&vUk", + "1&vUE", + "1&vUc", "1&vc", "1&vf(", + "1&vk1", + "1&vkf", + "1&vks", + "1&vkv", "1&vo(", "1&vo1", + "1&voE", "1&vof", - "1&vok", "1&von", "1&voo", "1&vos", "1&vov", + "1&vso", + "1((((", + "1(((E", + "1(((U", + "1((En", + "1((U(", + "1(Enk", + "1(U((", + "1(U(E", + "1)&((", "1)&(1", + "1)&(E", "1)&(f", - "1)&(k", - "1)&(n", "1)&(s", "1)&(v", + "1)&1", + "1)&1&", "1)&1B", "1)&1U", + "1)&1c", "1)&1f", "1)&1o", "1)&f(", "1)&o(", + "1)&s", + "1)&s&", "1)&sB", "1)&sU", + "1)&sc", "1)&sf", "1)&so", + "1)&v", + "1)&v&", "1)&vB", "1)&vU", + "1)&vc", "1)&vf", "1)&vo", - "1)()s", - "1)()v", "1))&(", "1))&1", "1))&f", + "1))&n", "1))&o", "1))&s", "1))&v", "1)))&", "1))))", + "1))),", "1)));", "1)))B", + "1)))E", "1)))U", - "1)))c", "1)))k", "1)))o", - "1));c", - "1));k", + "1)),(", + "1));E", "1))B1", + "1))Bf", "1))Bs", "1))Bv", - "1))Uk", - "1))Un", - "1))c", + "1))E1", + "1))Ef", + "1))Es", + "1))Ev", + "1))U(", + "1))UE", "1))k1", - "1))kk", + "1))kf", + "1))kn", "1))ks", "1))kv", "1))o(", "1))o1", + "1))oE", "1))of", - "1))ok", "1))on", "1))os", "1))ov", + "1),((", "1),(1", + "1),(f", "1),(s", "1),(v", - "1);c", - "1);k&", - "1);k(", - "1);kf", - "1);kk", - "1);kn", - "1);ko", + "1);E&", + "1);E(", + "1);E1", + "1);Ef", + "1);Eo", + "1);Es", + "1);Ev", "1)B1", "1)B1&", "1)B1c", "1)B1o", + "1)Bf(", "1)Bs", "1)Bs&", "1)Bsc", @@ -1199,598 +1382,1544 @@ static const char* sql_fingerprints[] = { "1)Bv&", "1)Bvc", "1)Bvo", - "1)U(k", - "1)Uk(", - "1)Uk1", - "1)Ukf", - "1)Ukk", - "1)Ukn", - "1)Uko", - "1)Uks", - "1)Ukv", - "1)Unk", - "1)c", - "1)k1", - "1)k1c", + "1)E1c", + "1)E1o", + "1)Ef(", + "1)Esc", + "1)Eso", + "1)Evc", + "1)Evo", + "1)U((", + "1)U(E", + "1)UE(", + "1)UE1", + "1)UEf", + "1)UEk", + "1)UEn", + "1)UEs", + "1)UEv", + "1)k1&", + "1)k1;", + "1)k1B", + "1)k1E", + "1)k1U", "1)k1o", - "1)kks", - "1)kkv", + "1)kf(", "1)knk", - "1)ks", - "1)ksc", + "1)ks&", + "1)ks;", + "1)ksB", + "1)ksE", + "1)ksU", "1)kso", - "1)kv", - "1)kvc", + "1)kv&", + "1)kv;", + "1)kvB", + "1)kvE", + "1)kvU", "1)kvo", - "1)o(1", - "1)o(k", + "1)o((", "1)o(n", - "1)o(s", - "1)o(v", + "1)o1", "1)o1)", - "1)o1B", "1)o1U", - "1)o1f", - "1)o1k", + "1)o1c", "1)o1o", + "1)oE(", "1)of(", - "1)ok(", - "1)ok1", - "1)oks", - "1)okv", + "1)on", "1)on&", + "1)onc", + "1)os", "1)os)", - "1)osB", "1)osU", - "1)osf", - "1)osk", + "1)osc", "1)oso", + "1)ov", "1)ov)", - "1)ovB", "1)ovU", - "1)ovf", - "1)ovk", + "1)ovc", "1)ovo", + "1,(((", + "1,((E", + "1,((f", + "1,(E(", + "1,(E1", + "1,(Ef", + "1,(Es", + "1,(Ev", "1,(f(", - "1,(k(", - "1,(k1", - "1,(kf", - "1,(ks", - "1,(kv", + "1,1))", "1,1),", "1,1)o", "1,1B1", + "1,1Bf", "1,1Bs", "1,1Bv", - "1,1Uk", + "1,1UE", + "1,1of", + "1,1os", + "1,1ov", + "1,f((", "1,f(1", + "1,f(f", "1,f(s", "1,f(v", + "1,s))", "1,s),", "1,s)o", "1,sB1", + "1,sBf", "1,sBs", "1,sBv", - "1,sUk", + "1,sUE", + "1,so1", + "1,sof", + "1,son", + "1,sos", + "1,sov", + "1,v))", "1,v),", "1,v)o", "1,vB1", + "1,vBf", "1,vBs", "1,vBv", - "1,vUk", - "1;c", - "1;k&k", - "1;k((", - "1;k(1", - "1;k(o", - "1;k(s", - "1;k(v", - "1;k1,", - "1;kf(", - "1;kks", - "1;kkv", - "1;kn(", - "1;kn,", - "1;knc", - "1;ko(", - "1;kok", - "1;ks,", - "1;kv,", + "1,vUE", + "1,vo1", + "1,vof", + "1,von", + "1,vos", + "1,vov", + "1:n:1", + "1:n:f", + "1:n:s", + "1:n:v", + "1;E&k", + "1;E((", + "1;E(1", + "1;E(E", + "1;E(f", + "1;E(s", + "1;E(v", + "1;E1,", + "1;E1;", + "1;E1E", + "1;E1c", + "1;E1o", + "1;E;", + "1;E;c", + "1;EEn", + "1;Ef(", + "1;En,", + "1;EnE", + "1;Enc", + "1;Enk", + "1;Eo(", + "1;Es,", + "1;Es;", + "1;EsE", + "1;Esc", + "1;Eso", + "1;Ev,", + "1;Ev;", + "1;EvE", + "1;Evc", + "1;Evo", + "1;n:k", "1B1", + "1B1&1", + "1B1&f", + "1B1&s", + "1B1&v", "1B1,1", + "1B1,f", "1B1,n", "1B1,s", "1B1,v", - "1B1Uk", + "1B1UE", "1B1c", "1B1k1", + "1B1kf", "1B1ks", "1B1kv", + "1B1of", + "1B1os", + "1B1ov", + "1BE((", + "1BE(1", + "1BE(f", + "1BE(s", + "1BE(v", + "1Bf((", "1Bf(1", "1Bf(f", "1Bf(s", "1Bf(v", - "1Bk(1", - "1Bk(s", - "1Bk(v", "1Bn,n", "1Bnk1", + "1Bnkf", "1Bnks", "1Bnkv", "1Bs", + "1Bs&1", + "1Bs&f", + "1Bs&s", + "1Bs&v", "1Bs,1", + "1Bs,f", "1Bs,n", "1Bs,s", "1Bs,v", - "1BsUk", + "1BsUE", "1Bsc", "1Bsk1", + "1Bskf", "1Bsks", "1Bskv", + "1Bso1", + "1Bsof", + "1Bson", + "1Bsos", + "1Bsov", "1Bv", + "1Bv&1", + "1Bv&f", + "1Bv&s", + "1Bv&v", "1Bv,1", + "1Bv,f", "1Bv,n", "1Bv,s", "1Bv,v", - "1BvUk", + "1BvUE", "1Bvc", "1Bvk1", + "1Bvkf", "1Bvks", "1Bvkv", + "1Bvo1", + "1Bvof", + "1Bvon", + "1Bvos", + "1Bvov", + "1E1c", + "1E1of", + "1E1os", + "1E1ov", + "1EU1,", + "1EU1o", + "1EUEf", + "1EUf(", + "1EUs,", + "1EUso", + "1EUv,", + "1EUvo", + "1Ef((", + "1Ef(1", + "1Ef(f", + "1Ef(s", + "1Ef(v", + "1EnEn", + "1Eokn", + "1Esc", + "1Eso1", + "1Esof", + "1Eson", + "1Esos", + "1Esov", + "1Evc", + "1Evo1", + "1Evof", + "1Evon", + "1Evos", + "1Evov", "1U", - "1U((k", - "1U(k1", - "1U(kf", - "1U(kn", - "1U(ks", - "1U(kv", + "1U(((", + "1U((E", + "1U(E(", + "1U(E1", + "1U(Ef", + "1U(En", + "1U(Es", + "1U(Ev", "1U1,1", + "1U1,f", "1U1,s", "1U1,v", + "1U1of", + "1U1os", + "1U1ov", + "1UE", + "1UE((", + "1UE(1", + "1UE(E", + "1UE(f", + "1UE(s", + "1UE(v", + "1UE1", + "1UE1&", + "1UE1,", + "1UE1c", + "1UE1f", + "1UE1k", + "1UE1n", + "1UE1o", + "1UEc", + "1UEf", + "1UEf(", + "1UEf,", + "1UEfc", + "1UEk1", + "1UEkf", + "1UEkn", + "1UEks", + "1UEkv", + "1UEn&", + "1UEn,", + "1UEn1", + "1UEnc", + "1UEnf", + "1UEnk", + "1UEno", + "1UEns", + "1UEok", + "1UEs", + "1UEs&", + "1UEs,", + "1UEsc", + "1UEsf", + "1UEsk", + "1UEsn", + "1UEso", + "1UEv", + "1UEv&", + "1UEv,", + "1UEvc", + "1UEvf", + "1UEvk", + "1UEvn", + "1UEvo", "1Uc", - "1Uk", - "1Uk(1", - "1Uk(k", - "1Uk(n", - "1Uk(s", - "1Uk(v", - "1Uk1", - "1Uk1,", - "1Uk1c", - "1Uk1f", - "1Uk1k", - "1Uk1n", - "1Uk1o", - "1Ukf", - "1Ukf(", - "1Ukf,", - "1Ukk(", - "1Ukk,", - "1Ukk1", - "1Ukkk", - "1Ukkn", - "1Ukks", - "1Ukkv", - "1Ukn&", - "1Ukn(", - "1Ukn,", - "1Ukn1", - "1Uknc", - "1Uknk", - "1Ukno", - "1Ukns", - "1Uknv", - "1Uko1", - "1Ukok", - "1Ukos", - "1Ukov", - "1Uks", - "1Uks,", - "1Uksc", - "1Uksf", - "1Uksk", - "1Uksn", - "1Ukso", - "1Ukv", - "1Ukv,", - "1Ukvc", - "1Ukvf", - "1Ukvk", - "1Ukvn", - "1Ukvo", + "1Uf((", + "1Uf(1", + "1Uf(f", + "1Uf(s", + "1Uf(v", + "1Uk((", + "1Uk(E", "1Un,1", + "1Un,f", "1Un,s", "1Un,v", "1Un1,", - "1Unk(", - "1Unk1", - "1Unkf", - "1Unks", - "1Unkv", - "1Uns,", - "1Unv,", + "1Un1o", + "1UnE1", + "1UnEf", + "1UnEs", + "1UnEv", + "1Unc", + "1Unf(", + "1Uo((", + "1Uo(E", "1Uon1", - "1Uons", - "1Uonv", + "1Uonf", "1Us,1", + "1Us,f", "1Us,s", "1Us,v", + "1Uso1", + "1Usof", + "1Uson", + "1Usos", + "1Usov", "1Uv,1", + "1Uv,f", "1Uv,s", "1Uv,v", + "1Uvo1", + "1Uvof", + "1Uvon", + "1Uvos", + "1Uvov", "1c", + "1f(((", + "1f(()", + "1f((1", + "1f((f", + "1f((n", + "1f((s", + "1f((v", + "1f())", "1f()k", + "1f(1)", + "1f(1o", + "1f(f(", + "1f(n,", + "1f(s)", + "1f(so", + "1f(v)", + "1f(vo", + "1k(((", + "1k((1", + "1k((f", + "1k((s", + "1k((v", + "1k(1)", + "1k(1o", + "1k(f(", + "1k(s)", + "1k(so", + "1k(v)", + "1k(vo", + "1k)&(", + "1k)&1", + "1k)&f", + "1k)&s", + "1k)&v", + "1k))&", + "1k)))", + "1k));", + "1k))B", + "1k))E", + "1k))U", + "1k))k", + "1k))o", + "1k);E", + "1k)B1", + "1k)Bf", + "1k)Bs", + "1k)Bv", + "1k)E1", + "1k)Ef", + "1k)Es", + "1k)Ev", + "1k)UE", + "1k)oE", + "1k1", + "1k1&(", + "1k1&1", + "1k1&f", + "1k1&o", + "1k1&s", + "1k1&v", + "1k1;E", + "1k1B1", + "1k1Bf", + "1k1Bs", + "1k1Bv", + "1k1E1", + "1k1Ef", + "1k1Es", + "1k1Ev", "1k1U(", - "1k1Uk", + "1k1UE", "1k1c", - "1k1o1", + "1k1oE", + "1k1of", + "1k1os", "1k1ov", - "1kU1,", - "1kUs,", - "1kUv,", + "1kf((", "1kf(1", + "1kf(f", "1kf(s", "1kf(v", - "1kk(1", - "1kk(s", - "1kk(v", - "1kksc", - "1kkvc", - "1knkn", - "1kno1", - "1knov", - "1kokn", + "1knc", + "1ks", + "1ks&(", + "1ks&1", + "1ks&f", + "1ks&o", + "1ks&s", + "1ks&v", + "1ks;E", + "1ksB1", + "1ksBf", + "1ksBs", + "1ksBv", + "1ksE1", + "1ksEf", + "1ksEs", + "1ksEv", "1ksU(", - "1ksUk", + "1ksUE", "1ksc", + "1kso1", + "1ksoE", + "1ksof", + "1kson", + "1ksos", + "1ksov", + "1kv", + "1kv&(", + "1kv&1", + "1kv&f", + "1kv&o", + "1kv&s", + "1kv&v", + "1kv;E", + "1kvB1", + "1kvBf", + "1kvBs", + "1kvBv", + "1kvE1", + "1kvEf", + "1kvEs", + "1kvEv", "1kvU(", - "1kvUk", + "1kvUE", "1kvc", "1kvo1", + "1kvoE", + "1kvof", + "1kvon", + "1kvos", "1kvov", "1n&f(", - "1n)Uk", - "1nUk1", - "1nUkn", - "1nUks", - "1nUkv", - "1nk1c", - "1nkf(", - "1nksc", - "1nkvc", + "1n)))", + "1n))U", + "1n))n", + "1n)UE", + "1n,f(", + "1n1c", + "1n1of", + "1n1os", + "1n1ov", + "1nE1c", + "1nE1o", + "1nEf(", + "1nEsc", + "1nEso", + "1nEvc", + "1nEvo", + "1nU((", + "1nU(E", + "1nUE1", + "1nUEf", + "1nUEs", + "1nUEv", + "1nf((", + "1nf(1", + "1nf(f", + "1nf(s", + "1nf(v", + "1no((", + "1no(1", + "1no(f", + "1no(s", + "1no(v", + "1nof(", + "1nosU", + "1noso", + "1novU", + "1novo", "1o(((", "1o((1", + "1o((E", "1o((f", + "1o((n", + "1o((o", "1o((s", "1o((v", "1o(1)", "1o(1o", + "1o(E(", + "1o(E1", + "1o(EE", + "1o(Ef", + "1o(En", + "1o(Es", + "1o(Ev", "1o(f(", - "1o(k(", - "1o(k1", - "1o(kf", - "1o(kn", - "1o(ks", - "1o(kv", "1o(n)", "1o(o1", + "1o(of", "1o(os", "1o(ov", "1o(s)", "1o(so", "1o(v)", "1o(vo", - "1o1)&", - "1o1)o", - "1o1Bf", - "1o1Uk", - "1o1f(", - "1o1kf", - "1o1o(", - "1o1o1", - "1o1of", - "1o1oo", - "1o1os", - "1o1ov", + "1oE((", + "1oE(1", + "1oE(f", + "1oE(s", + "1oE(v", + "1oEUE", + "1oU((", + "1oU(E", + "1of((", "1of()", "1of(1", "1of(f", - "1of(n", "1of(s", "1of(v", + "1ok&1", + "1ok&f", + "1ok&s", + "1ok&v", + "1ok((", "1ok(1", - "1ok(k", + "1ok(f", "1ok(s", "1ok(v", - "1ok)U", - "1ok)o", - "1ok1", - "1ok1,", "1ok1c", - "1ok1k", - "1okUk", + "1ok1o", "1okf(", - "1oks", - "1oks,", + "1oko1", + "1okof", + "1okos", + "1okov", "1oksc", - "1oksk", - "1okv", - "1okv,", + "1okso", "1okvc", - "1okvk", - "1onos", - "1onov", + "1okvo", + "1os&(", + "1os&1", + "1os&E", + "1os&U", + "1os&f", + "1os&k", + "1os&n", + "1os&o", + "1os&s", + "1os&v", + "1os((", + "1os(E", + "1os(U", "1os)&", + "1os))", + "1os),", + "1os);", + "1os)B", + "1os)E", "1os)U", + "1os)k", "1os)o", + "1os,(", + "1os,1", + "1os,f", + "1os,s", + "1os,v", + "1os1:", + "1os1f", + "1os1o", + "1os1s", + "1os1v", + "1os:n", + "1os;E", + "1os;n", + "1osB1", + "1osBE", "1osBf", + "1osBn", + "1osBs", + "1osBv", + "1osE1", + "1osEU", + "1osEf", + "1osEn", + "1osEo", + "1osEs", + "1osEv", + "1osU", + "1osU(", + "1osU1", + "1osUE", + "1osUc", + "1osUf", "1osUk", + "1osUn", + "1osUo", + "1osUs", + "1osUv", + "1osc", "1osf(", + "1osk(", + "1osk)", + "1osk1", "1oskf", + "1oskn", + "1osks", + "1oskv", + "1osn&", + "1osn)", + "1osn,", + "1osn1", + "1osnE", + "1osnU", + "1osnf", + "1osno", "1oso(", "1oso1", + "1osoE", + "1osoU", "1osof", - "1osoo", + "1osok", + "1oson", "1osos", "1osov", + "1osv:", + "1osvf", + "1osvo", + "1osvs", + "1ov", + "1ov&(", + "1ov&1", + "1ov&E", + "1ov&U", + "1ov&f", + "1ov&k", + "1ov&n", + "1ov&o", + "1ov&s", + "1ov&v", + "1ov((", + "1ov(E", + "1ov(U", "1ov)&", + "1ov))", + "1ov),", + "1ov);", + "1ov)B", + "1ov)E", "1ov)U", + "1ov)k", "1ov)o", + "1ov,(", + "1ov,1", + "1ov,f", + "1ov,s", + "1ov,v", + "1ov:n", + "1ov;E", + "1ov;n", + "1ovB1", + "1ovBE", "1ovBf", + "1ovBn", + "1ovBs", + "1ovBv", + "1ovE1", + "1ovEU", + "1ovEf", + "1ovEn", + "1ovEo", + "1ovEs", + "1ovEv", + "1ovU", + "1ovU(", + "1ovU1", + "1ovUE", + "1ovUc", + "1ovUf", "1ovUk", + "1ovUn", + "1ovUo", + "1ovUs", + "1ovUv", + "1ovc", "1ovf(", + "1ovk(", + "1ovk)", + "1ovk1", "1ovkf", + "1ovkn", + "1ovks", + "1ovkv", + "1ovn&", + "1ovn)", + "1ovn,", + "1ovn1", + "1ovnE", + "1ovnU", + "1ovnf", + "1ovno", "1ovo(", "1ovo1", + "1ovoE", + "1ovoU", "1ovof", - "1ovoo", + "1ovok", + "1ovon", "1ovos", "1ovov", - ";kknc", - "Uk1,1", - "Uk1,f", - "Uk1,n", - "Uk1,s", - "Uk1,v", - "Ukkkn", - "Uks,1", - "Uks,f", - "Uks,n", - "Uks,s", - "Uks,v", - "Ukv,1", - "Ukv,f", - "Ukv,n", - "Ukv,s", - "Ukv,v", + "1ovs1", + "1ovs:", + "1ovsf", + "1ovso", + "1ovsv", + "1s1", + "1s1c", + "1s1of", + "1s1os", + "1s1ov", + "1s:1:", + "1s:1o", + "1s:f(", + "1s:s:", + "1s:so", + "1s:v:", + "1s:vo", + "1sf((", + "1sf(1", + "1sf(f", + "1sf(s", + "1sf(v", + "1so1f", + "1so1o", + "1so1s", + "1so1v", + "1sof(", + "1son1", + "1sonf", + "1sos1", + "1sosf", + "1soso", + "1sosv", + "1sovf", + "1sovo", + "1sovs", + "1sv", + "1svc", + "1svo1", + "1svof", + "1svon", + "1svos", + "1svov", + "1v:1:", + "1v:1o", + "1v:f(", + "1v:s:", + "1v:so", + "1v:v:", + "1v:vo", + "1vf((", + "1vf(1", + "1vf(f", + "1vf(s", + "1vf(v", + "1vo1f", + "1vo1o", + "1vo1s", + "1vo1v", + "1vof(", + "1von1", + "1vonf", + "1vos1", + "1vosf", + "1voso", + "1vosv", + "1vovf", + "1vovo", + "1vovs", + "1vs", + "1vsc", + "1vso1", + "1vsof", + "1vson", + "1vsos", + "1vsov", + ";Eknc", + "E((((", + "E(((1", + "E(((E", + "E(((f", + "E(((n", + "E(((s", + "E(((v", + "E((1)", + "E((1f", + "E((1o", + "E((1s", + "E((1v", + "E((Ek", + "E((f(", + "E((n)", + "E((s)", + "E((s1", + "E((sf", + "E((so", + "E((sv", + "E((v)", + "E((vf", + "E((vo", + "E((vs", + "E(1))", + "E(1),", + "E(1f(", + "E(1of", + "E(1os", + "E(1ov", + "E(1s)", + "E(1so", + "E(1v)", + "E(1vo", + "E(Ek(", + "E(f((", + "E(f(1", + "E(f(f", + "E(f(s", + "E(f(v", + "E(n))", + "E(n),", + "E(s))", + "E(s),", + "E(s1)", + "E(s1o", + "E(sf(", + "E(so1", + "E(sof", + "E(son", + "E(sos", + "E(sov", + "E(sv)", + "E(svo", + "E(v))", + "E(v),", + "E(vf(", + "E(vo1", + "E(vof", + "E(von", + "E(vos", + "E(vov", + "E(vs)", + "E(vso", + "E(vv)", + "E1&((", + "E1&(E", + "E1)", + "E1))", + "E1)))", + "E1))1", + "E1))c", + "E1))f", + "E1))s", + "E1))v", + "E1)c", + "E1,((", + "E1,(1", + "E1,(f", + "E1,(s", + "E1,(v", + "E1,1,", + "E1,1k", + "E1,1o", + "E1,f(", + "E1,n,", + "E1,s,", + "E1,sk", + "E1,so", + "E1,v,", + "E1,vk", + "E1,vo", + "E1f((", + "E1f(1", + "E1f(f", + "E1f(s", + "E1f(v", + "E1k((", + "E1k(E", + "E1k1k", + "E1k1o", + "E1kf(", + "E1knk", + "E1ksk", + "E1kso", + "E1kvk", + "E1kvo", + "E1o((", + "E1o(1", + "E1o(f", + "E1o(s", + "E1o(v", + "E1of(", + "E1os1", + "E1osf", + "E1oso", + "E1osv", + "E1ovf", + "E1ovo", + "E1ovs", + "EE(((", + "EE((f", + "EE(f(", + "Ef(((", + "Ef((1", + "Ef((f", + "Ef((n", + "Ef((o", + "Ef((s", + "Ef((v", + "Ef(1)", + "Ef(1,", + "Ef(1o", + "Ef(f(", + "Ef(n)", + "Ef(n,", + "Ef(o)", + "Ef(s)", + "Ef(s,", + "Ef(so", + "Ef(v)", + "Ef(v,", + "Ef(vo", + "Ek1f(", + "Ek1k1", + "Ek1kf", + "Ek1kn", + "Ek1ks", + "Ek1kv", + "Ek1nk", + "Ek1of", + "Ek1os", + "Ek1ov", + "Ek1sf", + "Ek1sk", + "Ek1so", + "Ek1vf", + "Ek1vk", + "Ek1vo", + "Ekf((", + "Ekf(1", + "Ekf(f", + "Ekf(s", + "Ekf(v", + "Eks1f", + "Eks1k", + "Eks1o", + "Eksf(", + "Eksk1", + "Ekskf", + "Ekskn", + "Eksks", + "Ekskv", + "Eksnk", + "Ekso1", + "Eksof", + "Ekson", + "Eksos", + "Eksov", + "Eksvf", + "Eksvk", + "Eksvo", + "Ekvf(", + "Ekvk1", + "Ekvkf", + "Ekvkn", + "Ekvks", + "Ekvkv", + "Ekvnk", + "Ekvo1", + "Ekvof", + "Ekvon", + "Ekvos", + "Ekvov", + "Ekvsf", + "Ekvsk", + "Ekvso", + "En,f(", + "En,n,", + "Enk((", + "Enk(E", + "Enknk", + "Eo(((", + "Eo((1", + "Eo((f", + "Eo((s", + "Eo((v", + "Eo(1,", + "Eo(1o", + "Eo(f(", + "Eo(s,", + "Eo(so", + "Eo(v,", + "Eo(vo", + "Eok((", + "Eok(E", + "Es&((", + "Es&(E", + "Es)", + "Es))", + "Es)))", + "Es))1", + "Es))c", + "Es))f", + "Es))s", + "Es))v", + "Es)c", + "Es,((", + "Es,(1", + "Es,(f", + "Es,(s", + "Es,(v", + "Es,1,", + "Es,1k", + "Es,1o", + "Es,f(", + "Es,n,", + "Es,s,", + "Es,sk", + "Es,so", + "Es,v,", + "Es,vk", + "Es,vo", + "Esf((", + "Esf(1", + "Esf(f", + "Esf(s", + "Esf(v", + "Esk((", + "Esk(E", + "Esk1k", + "Esk1o", + "Eskf(", + "Esknk", + "Esksk", + "Eskso", + "Eskvk", + "Eskvo", + "Eso((", + "Eso(1", + "Eso(f", + "Eso(s", + "Eso(v", + "Eso1f", + "Eso1o", + "Eso1s", + "Eso1v", + "Esof(", + "Eson1", + "Esonf", + "Esos1", + "Esosf", + "Esoso", + "Esosv", + "Esovf", + "Esovo", + "Esovs", + "Ev&((", + "Ev&(E", + "Ev)", + "Ev))", + "Ev)))", + "Ev))1", + "Ev))c", + "Ev))f", + "Ev))s", + "Ev))v", + "Ev)c", + "Ev,((", + "Ev,(1", + "Ev,(f", + "Ev,(s", + "Ev,(v", + "Ev,1,", + "Ev,1k", + "Ev,1o", + "Ev,f(", + "Ev,n,", + "Ev,s,", + "Ev,sk", + "Ev,so", + "Ev,v,", + "Ev,vk", + "Ev,vo", + "Evf((", + "Evf(1", + "Evf(f", + "Evf(s", + "Evf(v", + "Evk((", + "Evk(E", + "Evk1k", + "Evk1o", + "Evkf(", + "Evknk", + "Evksk", + "Evkso", + "Evkvk", + "Evkvo", + "Evo((", + "Evo(1", + "Evo(f", + "Evo(s", + "Evo(v", + "Evo1f", + "Evo1o", + "Evo1s", + "Evo1v", + "Evof(", + "Evon1", + "Evonf", + "Evos1", + "Evosf", + "Evoso", + "Evosv", + "Evovf", + "Evovo", + "Evovs", + "U((((", + "U(((E", + "U((En", + "U(Enk", + "UE(((", + "UE((1", + "UE((f", + "UE((s", + "UE((v", + "UE(1,", + "UE(1o", + "UE(f(", + "UE(s,", + "UE(so", + "UE(v,", + "UE(vo", + "UE1,1", + "UE1,f", + "UE1,n", + "UE1,s", + "UE1,v", + "UE1of", + "UE1os", + "UE1ov", + "UEf((", + "UEf(1", + "UEf(f", + "UEf(s", + "UEf(v", + "UEnkn", + "UEs,1", + "UEs,f", + "UEs,n", + "UEs,s", + "UEs,v", + "UEso1", + "UEsof", + "UEson", + "UEsos", + "UEsov", + "UEv,1", + "UEv,f", + "UEv,n", + "UEv,s", + "UEv,v", + "UEvo1", + "UEvof", + "UEvon", + "UEvos", + "UEvov", + "Uf(((", + "Uf((1", + "Uf((f", + "Uf((s", + "Uf((v", + "Uf(1)", + "Uf(1o", + "Uf(f(", + "Uf(s)", + "Uf(so", + "Uf(v)", + "Uf(vo", + "f((((", + "f((()", + "f(((1", + "f(((E", + "f(((f", + "f(((k", + "f(((s", + "f(((v", + "f(()&", + "f(())", + "f(()o", + "f((1)", + "f((1,", + "f((1o", + "f((E(", + "f((Ef", "f((f(", "f((k(", - "f((kf", + "f((k,", + "f((s)", + "f((s,", + "f((so", + "f((v)", + "f((v,", + "f((vo", "f()&f", - "f()of", + "f())&", + "f()))", + "f())o", + "f()ok", "f(1)&", + "f(1))", + "f(1),", + "f(1)1", + "f(1):", + "f(1);", + "f(1)B", + "f(1)E", "f(1)U", + "f(1)c", + "f(1)f", + "f(1)k", + "f(1)n", "f(1)o", + "f(1)s", + "f(1)v", "f(1,1", "f(1,f", + "f(1,n", "f(1,s", "f(1,v", - "f(1o1", + "f(1of", "f(1os", "f(1ov", + "f(f((", "f(f()", "f(f(1", "f(f(f", "f(f(s", "f(f(v", + "f(k((", "f(k()", "f(k,(", "f(k,f", - "f(k,n", - "f(n()", "f(s)&", + "f(s))", + "f(s),", + "f(s)1", + "f(s):", + "f(s);", + "f(s)B", + "f(s)E", "f(s)U", + "f(s)c", + "f(s)f", + "f(s)k", + "f(s)n", "f(s)o", + "f(s)s", + "f(s)v", "f(s,1", "f(s,f", + "f(s,n", "f(s,s", "f(s,v", "f(so1", + "f(sof", + "f(son", "f(sos", "f(sov", "f(v)&", + "f(v))", + "f(v),", + "f(v)1", + "f(v):", + "f(v);", + "f(v)B", + "f(v)E", "f(v)U", + "f(v)c", + "f(v)f", + "f(v)k", + "f(v)n", "f(v)o", + "f(v)s", + "f(v)v", "f(v,1", "f(v,f", + "f(v,n", "f(v,s", "f(v,v", "f(vo1", + "f(vof", + "f(von", "f(vos", "f(vov", - "k()ok", - "k(1)U", - "k(f(1", - "k(f(v", - "k(ok(", - "k(s)U", - "k(sv)", - "k(v)U", - "k(vs)", - "k(vv)", - "k1,1,", + "ff(((", + "ff((1", + "ff((f", + "ff((s", + "ff((v", + "ff(1)", + "ff(1o", + "ff(f(", + "ff(s)", + "ff(so", + "ff(v)", + "ff(vo", "k1,1c", - "k1,1k", + "k1,1o", "k1,f(", - "k1,n,", - "k1,s,", "k1,sc", - "k1,sk", - "k1,v,", + "k1,so", "k1,vc", - "k1,vk", - "k1k(k", - "k1kf(", - "k1o(s", - "k1o(v", - "k;non", - "kc", + "k1,vo", + "k1of(", + "k1os1", + "k1osf", + "k1oso", + "k1osv", + "k1ovf", + "k1ovo", + "k1ovs", + "kf(((", + "kf((1", "kf((f", + "kf((s", + "kf((v", "kf(1)", - "kf(1,", + "kf(1o", "kf(f(", - "kf(n,", - "kf(o)", "kf(s)", - "kf(s,", - "kf(s:", + "kf(so", "kf(v)", - "kf(v,", - "kf(v:", - "kk(f(", - "kk1f(", - "kk1fn", - "kk1kk", - "kk1nk", - "kk1sf", - "kk1sk", - "kk1sn", - "kk1vf", - "kk1vk", - "kk1vn", - "kksf(", - "kksfn", - "kkskk", - "kksnk", - "kksvk", - "kksvn", - "kkvf(", - "kkvfn", - "kkvkk", - "kkvnk", - "kkvsf", - "kkvsk", - "kkvsn", - "kkvvf", - "kkvvk", - "kkvvn", - "kn1kk", - "kn1sk", - "kn1sn", - "kn1vk", - "kn1vn", - "knk(k", - "knskk", - "knsvk", - "knsvn", - "knvkk", - "knvsk", - "knvsn", - "knvvk", - "knvvn", - "ko(k(", - "ko(kf", - "ko(n,", - "ko(s,", - "ko(v,", - "kok(k", - "ks&(k", - "ks&(o", - "ks)", - "ks,1,", + "kf(vo", "ks,1c", - "ks,1k", + "ks,1o", "ks,f(", - "ks,s,", "ks,sc", - "ks,sk", - "ks,v,", + "ks,so", "ks,vc", - "ks,vk", - "ksf(1", - "ksf(s", - "ksf(v", - "ksk(1", - "ksk(k", - "ksk(s", - "ksk(v", - "kso(s", - "kso(v", - "kv&(k", - "kv&(o", - "kv)", - "kv,1,", + "ks,vo", + "kso1f", + "kso1o", + "kso1s", + "kso1v", + "ksof(", + "kson1", + "ksonf", + "ksos1", + "ksosf", + "ksoso", + "ksosv", + "ksovf", + "ksovo", + "ksovs", "kv,1c", - "kv,1k", + "kv,1o", "kv,f(", - "kv,n,", - "kv,s,", "kv,sc", - "kv,sk", - "kv,v,", + "kv,so", "kv,vc", - "kv,vk", - "kvf(1", - "kvf(s", - "kvf(v", - "kvk(1", - "kvk(k", - "kvk(s", - "kvk(v", - "kvkf(", - "kvo(s", - "kvo(v", + "kv,vo", + "kvo1f", + "kvo1o", + "kvo1s", + "kvo1v", + "kvof(", + "kvon1", + "kvonf", + "kvos1", + "kvosf", + "kvoso", + "kvosv", + "kvovf", + "kvovo", + "kvovs", + "n&(((", + "n&((1", + "n&((E", + "n&((f", + "n&((o", + "n&((s", + "n&((v", "n&(1)", "n&(1,", - "n&(k1", - "n&(ks", - "n&(kv", + "n&(1o", + "n&(E1", + "n&(Ef", + "n&(Es", + "n&(Ev", + "n&(f(", "n&(o1", + "n&(of", "n&(os", "n&(ov", "n&(s)", "n&(s,", + "n&(so", "n&(v)", "n&(v,", + "n&(vo", + "n&1", + "n&1&n", "n&1Bf", + "n&1UE", + "n&1c", "n&1f(", "n&1o(", - "n&1o1", "n&1of", "n&1oo", "n&1os", "n&1ov", + "n&E((", + "n&E(1", + "n&E(f", + "n&E(s", + "n&E(v", + "n&f((", "n&f(1", "n&f(f", "n&f(s", "n&f(v", - "n&k(1", - "n&k(s", - "n&k(v", + "n&nUE", + "n&nof", + "n&nos", + "n&nov", + "n&o1", + "n&o1c", "n&o1o", + "n&of(", + "n&os", + "n&osc", "n&oso", + "n&ov", + "n&ovc", "n&ovo", + "n&s", + "n&s&n", + "n&sBf", + "n&sUE", + "n&sc", "n&sf(", "n&so(", "n&so1", "n&sof", + "n&son", "n&soo", "n&sos", "n&sov", + "n&v", + "n&v&n", "n&vBf", + "n&vUE", + "n&vc", "n&vf(", "n&vo(", "n&vo1", "n&vof", + "n&von", "n&voo", "n&vos", "n&vov", - "n)&(k", + "n)&((", + "n)&(E", + "n)&1", + "n)&1&", + "n)&1c", "n)&1f", "n)&1o", "n)&f(", + "n)&s", + "n)&s&", + "n)&sc", "n)&sf", "n)&so", + "n)&v", + "n)&v&", + "n)&vc", "n)&vf", "n)&vo", "n))&(", @@ -1799,194 +2928,344 @@ static const char* sql_fingerprints[] = { "n))&s", "n))&v", "n)))&", + "n))))", "n)));", "n)))B", + "n)))E", "n)))U", - "n)))c", "n)))k", "n)))o", - "n));c", - "n));k", + "n));E", "n))B1", + "n))Bf", + "n))Bs", "n))Bv", - "n))Uk", - "n))c", - "n))kk", - "n))o(", + "n))E1", + "n))Ef", + "n))Es", + "n))Ev", + "n))UE", + "n))k1", + "n))kf", + "n))ks", + "n))kv", "n))o1", + "n))oE", "n))of", - "n))ok", "n))os", "n))ov", - "n);c", - "n);k&", - "n);k(", - "n);kf", - "n);kk", - "n);kn", - "n);ko", + "n);E&", + "n);E(", + "n);E1", + "n);Ef", + "n);Eo", + "n);Es", + "n);Ev", "n)B1c", + "n)B1o", + "n)Bf(", + "n)Bsc", + "n)Bso", "n)Bvc", - "n)Uk1", - "n)Ukv", - "n)c", + "n)Bvo", + "n)E1c", + "n)E1o", + "n)Ef(", + "n)Esc", + "n)Eso", + "n)Evc", + "n)Evo", + "n)UE1", + "n)UEf", + "n)UEs", + "n)UEv", + "n)k1&", + "n)k1;", + "n)k1B", + "n)k1U", "n)k1o", - "n)kks", - "n)kkv", + "n)kf(", + "n)ks&", + "n)ks;", + "n)ksB", + "n)ksU", "n)kso", + "n)kv&", + "n)kv;", + "n)kvB", + "n)kvU", "n)kvo", - "n)o(k", "n)o1&", - "n)o1f", "n)o1o", + "n)oE(", "n)of(", - "n)ok(", "n)os&", - "n)osf", "n)oso", "n)ov&", - "n)ovf", "n)ovo", + "n,(((", + "n,((E", + "n,((f", + "n,(E(", + "n,(E1", + "n,(Ef", + "n,(Es", + "n,(Ev", "n,(f(", - "n,(k(", - "n,(k1", - "n,(kf", - "n,(ks", - "n,(kv", + "n,1,1", + "n,1,f", + "n,1,s", + "n,1,v", + "n,1of", + "n,1os", + "n,1ov", + "n,f((", "n,f(1", + "n,f(f", "n,f(s", "n,f(v", + "n,s,1", + "n,s,f", + "n,s,s", + "n,s,v", + "n,so1", + "n,sof", + "n,son", + "n,sos", + "n,sov", + "n,v,1", + "n,v,f", + "n,v,s", + "n,v,v", + "n,vo1", + "n,vof", + "n,von", + "n,vos", + "n,vov", "n:o1U", + "n:o1o", + "n:of(", "n:osU", + "n:oso", "n:ovU", - "n;c", - "n;k&k", - "n;k((", - "n;k(1", - "n;k(s", - "n;k(v", - "n;kf(", - "n;kks", - "n;kkv", - "n;kn(", - "n;ko(", - "n;kok", + "n:ovo", + "n;E&k", + "n;E((", + "n;E(1", + "n;E(f", + "n;E(s", + "n;E(v", + "n;E1;", + "n;E1c", + "n;E1o", + "n;Ef(", + "n;Eo(", + "n;Es;", + "n;Esc", + "n;Eso", + "n;Ev;", + "n;Evc", + "n;Evo", "nB1c", + "nB1of", + "nB1os", + "nB1ov", + "nBf((", + "nBf(1", + "nBf(f", + "nBf(s", + "nBf(v", + "nBsc", + "nBso1", + "nBsof", + "nBson", + "nBsos", + "nBsov", "nBvc", - "nUk(k", - "nUk1,", - "nUk1c", - "nUkf(", - "nUkn,", - "nUks,", - "nUkv,", - "nUkvc", - "nUnk(", + "nBvo1", + "nBvof", + "nBvon", + "nBvos", + "nBvov", + "nE1c", + "nE1of", + "nE1os", + "nE1ov", + "nEf((", + "nEf(1", + "nEf(f", + "nEf(s", + "nEf(v", + "nEsc", + "nEso1", + "nEsof", + "nEson", + "nEsos", + "nEsov", + "nEvc", + "nEvo1", + "nEvof", + "nEvon", + "nEvos", + "nEvov", + "nU(((", + "nU((E", + "nU(E1", + "nU(Ef", + "nU(En", + "nU(Es", + "nU(Ev", + "nUE((", + "nUE(E", + "nUE1,", + "nUE1c", + "nUE1o", + "nUEf(", + "nUEn,", + "nUEs,", + "nUEsc", + "nUEso", + "nUEv,", + "nUEvc", + "nUEvo", "nc", - "nk1Uk", - "nk1o1", + "nf(((", + "nf((1", + "nf((f", + "nf((s", + "nf((v", + "nf(1)", + "nf(1o", + "nf(f(", + "nf(s)", + "nf(so", + "nf(v)", + "nf(vo", + "nk1&(", + "nk1&1", + "nk1&f", + "nk1&s", + "nk1&v", + "nk1;E", + "nk1B1", + "nk1Bf", + "nk1Bs", + "nk1Bv", + "nk1UE", + "nk1oE", + "nk1of", + "nk1os", "nk1ov", + "nkf((", "nkf(1", + "nkf(f", "nkf(s", "nkf(v", - "nkksc", - "nkkvc", - "nksUk", - "nkvUk", + "nks&(", + "nks&1", + "nks&f", + "nks&s", + "nks&v", + "nks;E", + "nksB1", + "nksBf", + "nksBs", + "nksBv", + "nksUE", + "nkso1", + "nksoE", + "nksof", + "nkson", + "nksos", + "nksov", + "nkv&(", + "nkv&1", + "nkv&f", + "nkv&s", + "nkv&v", + "nkv;E", + "nkvB1", + "nkvBf", + "nkvBs", + "nkvBv", + "nkvUE", "nkvo1", + "nkvoE", + "nkvof", + "nkvon", + "nkvos", "nkvov", - "nnn)U", - "nno1U", - "nnosU", - "nnovU", - "no(k1", - "no(ks", - "no(kv", - "no(o1", - "no(os", - "no(ov", - "no1&1", - "no1&s", - "no1&v", - "no1Uk", - "no1f(", - "no1o(", - "no1of", - "no1oo", - "no1os", - "no1ov", + "no(((", + "no((E", + "no(E1", + "no(Ef", + "no(Es", + "no(Ev", + "noE((", + "noE(1", + "noE(f", + "noE(s", + "noE(v", + "nof((", "nof(1", + "nof(f", "nof(s", "nof(v", - "nok(1", - "nok(f", - "nok(k", - "nok(s", - "nok(v", - "nono1", - "nonov", - "nos&1", - "nos&s", - "nos&v", - "nosUk", - "nosf(", - "noso(", + "nosUE", "noso1", "nosof", - "nosoo", + "noson", "nosos", "nosov", - "nov&1", - "nov&s", - "nov&v", - "novUk", - "novf(", - "novo(", + "novUE", "novo1", "novof", - "novoo", + "novon", "novos", "novov", - "o1kf(", - "oUk1,", - "oUks,", - "oUkv,", - "oc", - "of()o", + "oUE1,", + "oUE1o", + "oUEf(", + "oUEs,", + "oUEso", + "oUEv,", + "oUEvo", + "of(((", + "of((1", + "of((f", + "of((s", + "of((v", "of(1)", + "of(1o", + "of(f(", "of(s)", + "of(so", "of(v)", - "ok1o1", - "ok1os", - "ok1ov", - "okkkn", - "okso1", - "oksos", - "oksov", - "okvo1", - "okvos", - "okvov", - "ook1,", - "ooks,", - "ookv,", - "oskf(", - "ovkf(", + "of(vo", + "ooE1,", + "ooE1o", + "ooEf(", + "ooEs,", + "ooEso", + "ooEv,", + "ooEvo", + "s&(((", + "s&((1", + "s&((E", "s&((f", - "s&((k", + "s&((s", + "s&((v", "s&(1)", "s&(1,", "s&(1o", + "s&(E1", + "s&(Ef", + "s&(Ek", + "s&(En", + "s&(Eo", + "s&(Es", + "s&(Ev", "s&(f(", - "s&(k(", - "s&(k)", - "s&(k1", - "s&(kc", - "s&(kf", - "s&(kk", - "s&(kn", - "s&(ko", - "s&(ks", - "s&(kv", "s&(s)", "s&(s,", "s&(so", @@ -1994,123 +3273,205 @@ static const char* sql_fingerprints[] = { "s&(v,", "s&(vo", "s&1", + "s&1&(", + "s&1&1", + "s&1&f", + "s&1&n", + "s&1&s", + "s&1&v", + "s&1B1", "s&1Bf", - "s&1Uk", + "s&1Bs", + "s&1Bv", + "s&1En", + "s&1U", + "s&1U(", + "s&1UE", + "s&1Uc", "s&1c", "s&1f(", + "s&1k1", + "s&1kf", + "s&1ks", + "s&1kv", "s&1o(", - "s&1o1", + "s&1oE", "s&1of", - "s&1ok", - "s&1on", "s&1oo", "s&1os", "s&1ov", + "s&1so", + "s&1vo", + "s&E((", + "s&E(1", + "s&E(f", + "s&E(o", + "s&E(s", + "s&E(v", + "s&E1k", + "s&E1o", + "s&Ef(", + "s&Ek1", + "s&Ekf", + "s&Eks", + "s&Ekv", + "s&Esk", + "s&Eso", + "s&Evk", + "s&Evo", "s&f((", "s&f()", "s&f(1", "s&f(f", - "s&f(k", "s&f(n", "s&f(s", "s&f(v", + "s&k&1", + "s&k&f", "s&k&s", "s&k&v", - "s&k(1", - "s&k(f", - "s&k(o", - "s&k(s", - "s&k(v", - "s&k1k", "s&k1o", - "s&kUk", - "s&kc", - "s&kk1", - "s&kks", - "s&kkv", + "s&kf(", "s&knk", "s&ko(", "s&ko1", + "s&kof", "s&kok", + "s&kon", "s&kos", "s&kov", - "s&ksk", "s&kso", - "s&kvk", "s&kvo", + "s&n", + "s&n&1", + "s&n&f", + "s&n&n", "s&n&s", "s&n&v", - "s&n()", - "s&no1", + "s&nc", + "s&nk1", + "s&nkf", + "s&nks", + "s&nkv", + "s&nof", "s&nos", "s&nov", + "s&o((", "s&o(1", - "s&o(k", + "s&o(f", "s&o(s", "s&o(v", + "s&o1", + "s&o1c", "s&o1o", - "s&okc", + "s&of(", "s&oko", "s&os", + "s&osc", "s&oso", "s&ov", + "s&ovc", "s&ovo", "s&s", - "s&s:o", + "s&s&(", + "s&s&1", + "s&s&f", + "s&s&n", + "s&s&s", + "s&s&v", + "s&s1o", + "s&sB1", "s&sBf", + "s&sBs", + "s&sBv", + "s&sEn", + "s&sU", "s&sU(", - "s&sUk", + "s&sUE", + "s&sUc", "s&sc", "s&sf(", + "s&sk1", + "s&skf", + "s&sks", + "s&skv", "s&so(", "s&so1", + "s&soE", "s&sof", - "s&sok", "s&son", "s&soo", "s&sos", "s&sov", "s&svo", "s&v", - "s&v:o", + "s&v&(", + "s&v&1", + "s&v&f", + "s&v&n", + "s&v&s", + "s&v&v", + "s&vB1", "s&vBf", + "s&vBs", + "s&vBv", + "s&vEn", + "s&vU", "s&vU(", - "s&vUk", + "s&vUE", + "s&vUc", "s&vc", "s&vf(", + "s&vk1", + "s&vkf", + "s&vks", + "s&vkv", "s&vo(", "s&vo1", + "s&voE", "s&vof", - "s&vok", "s&von", "s&voo", "s&vos", "s&vov", "s&vso", - "s&vvo", - "s(c", + "s((((", + "s(((E", + "s(((U", + "s((En", + "s((U(", + "s(Enk", + "s(U((", + "s(U(E", + "s)&((", "s)&(1", + "s)&(E", "s)&(f", - "s)&(k", - "s)&(n", "s)&(s", "s)&(v", + "s)&1", + "s)&1&", "s)&1B", "s)&1U", + "s)&1c", "s)&1f", "s)&1o", "s)&f(", "s)&o(", + "s)&s", + "s)&s&", "s)&sB", "s)&sU", + "s)&sc", "s)&sf", "s)&so", + "s)&v", + "s)&v&", "s)&vB", "s)&vU", + "s)&vc", "s)&vf", "s)&vo", - "s)()s", - "s)()v", "s))&(", "s))&1", "s))&f", @@ -2120,45 +3481,54 @@ static const char* sql_fingerprints[] = { "s))&v", "s)))&", "s))))", + "s))),", "s)));", "s)))B", + "s)))E", "s)))U", - "s)))c", "s)))k", "s)))o", - "s));c", - "s));k", + "s)),(", + "s));E", "s))B1", + "s))Bf", "s))Bs", "s))Bv", - "s))Uk", - "s))Un", - "s))c", + "s))E1", + "s))Ef", + "s))Es", + "s))Ev", + "s))U(", + "s))UE", "s))k1", - "s))kk", + "s))kf", + "s))kn", "s))ks", "s))kv", "s))o(", "s))o1", + "s))oE", "s))of", - "s))ok", "s))on", "s))os", "s))ov", + "s),((", "s),(1", + "s),(f", "s),(s", "s),(v", - "s);c", - "s);k&", - "s);k(", - "s);kf", - "s);kk", - "s);kn", - "s);ko", + "s);E&", + "s);E(", + "s);E1", + "s);Ef", + "s);Eo", + "s);Es", + "s);Ev", "s)B1", "s)B1&", "s)B1c", "s)B1o", + "s)Bf(", "s)Bs", "s)Bs&", "s)Bsc", @@ -2167,493 +3537,1018 @@ static const char* sql_fingerprints[] = { "s)Bv&", "s)Bvc", "s)Bvo", - "s)U(k", - "s)Uk(", - "s)Uk1", - "s)Ukf", - "s)Ukk", - "s)Ukn", - "s)Uko", - "s)Uks", - "s)Ukv", - "s)Unk", - "s)c", - "s)k1", - "s)k1c", + "s)E1c", + "s)E1o", + "s)Ef(", + "s)Esc", + "s)Eso", + "s)Evc", + "s)Evo", + "s)U((", + "s)U(E", + "s)UE(", + "s)UE1", + "s)UEf", + "s)UEk", + "s)UEn", + "s)UEs", + "s)UEv", + "s)k1&", + "s)k1;", + "s)k1B", + "s)k1E", + "s)k1U", "s)k1o", - "s)kks", - "s)kkv", - "s)ks", - "s)ksc", + "s)kf(", + "s)knk", + "s)ks&", + "s)ks;", + "s)ksB", + "s)ksE", + "s)ksU", "s)kso", - "s)kv", - "s)kvc", + "s)kv&", + "s)kv;", + "s)kvB", + "s)kvE", + "s)kvU", "s)kvo", - "s)o(1", - "s)o(k", + "s)o((", "s)o(n", - "s)o(s", - "s)o(v", - "s)o1B", + "s)o1", + "s)o1)", "s)o1U", - "s)o1f", - "s)o1k", + "s)o1c", "s)o1o", + "s)oE(", "s)of(", - "s)ok(", - "s)ok1", - "s)oks", - "s)okv", + "s)on", "s)on&", + "s)onc", + "s)os", "s)os)", - "s)osB", "s)osU", - "s)osf", - "s)osk", + "s)osc", "s)oso", + "s)ov", "s)ov)", - "s)ovB", "s)ovU", - "s)ovf", - "s)ovk", + "s)ovc", "s)ovo", + "s,(((", + "s,((E", + "s,((f", + "s,(E(", + "s,(E1", + "s,(Ef", + "s,(Es", + "s,(Ev", "s,(f(", - "s,(k(", - "s,(k1", - "s,(kf", - "s,(ks", - "s,(kv", + "s,1))", "s,1),", "s,1)o", "s,1B1", + "s,1Bf", "s,1Bs", "s,1Bv", - "s,1Uk", + "s,1UE", + "s,1of", + "s,1os", + "s,1ov", + "s,f((", "s,f(1", + "s,f(f", "s,f(s", "s,f(v", + "s,s))", "s,s),", "s,s)o", "s,sB1", + "s,sBf", "s,sBs", "s,sBv", - "s,sUk", + "s,sUE", + "s,so1", + "s,sof", + "s,son", + "s,sos", + "s,sov", + "s,v))", "s,v),", "s,v)o", "s,vB1", + "s,vBf", "s,vBs", "s,vBv", - "s,vUk", - "s:o1)", - "s:os)", - "s:ov)", - "s;c", - "s;k&k", - "s;k((", - "s;k(1", - "s;k(o", - "s;k(s", - "s;k(v", - "s;k1,", - "s;k1o", - "s;k;", - "s;k[k", - "s;k[n", - "s;kf(", - "s;kkn", - "s;kks", - "s;kkv", - "s;kn(", - "s;kn,", - "s;knc", - "s;knk", - "s;knn", - "s;ko(", - "s;kok", - "s;ks,", - "s;ksc", - "s;ksk", - "s;kso", - "s;kv,", - "s;kvc", - "s;kvk", - "s;kvo", + "s,vUE", + "s,vo1", + "s,vof", + "s,von", + "s,vos", + "s,vov", + "s1:1:", + "s1:1o", + "s1:f(", + "s1:s:", + "s1:so", + "s1:v:", + "s1:vo", + "s1f((", + "s1f(1", + "s1f(f", + "s1f(s", + "s1f(v", + "s1of(", + "s1os1", + "s1osf", + "s1oso", + "s1osv", + "s1ovf", + "s1ovo", + "s1ovs", + "s1sc", + "s1so1", + "s1sof", + "s1son", + "s1sos", + "s1sov", + "s1v", + "s1vc", + "s1vo1", + "s1vof", + "s1von", + "s1vos", + "s1vov", + "s:n:1", + "s:n:f", + "s:n:s", + "s:n:v", + "s;E&k", + "s;E((", + "s;E(1", + "s;E(E", + "s;E(f", + "s;E(s", + "s;E(v", + "s;E1,", + "s;E1;", + "s;E1E", + "s;E1c", + "s;E1o", + "s;E;", + "s;E;c", + "s;EEn", + "s;Ef(", + "s;En,", + "s;EnE", + "s;Enc", + "s;Enk", + "s;Eo(", + "s;Es,", + "s;Es;", + "s;EsE", + "s;Esc", + "s;Eso", + "s;Ev,", + "s;Ev;", + "s;EvE", + "s;Evc", + "s;Evo", "s;n:k", "sB1", + "sB1&1", + "sB1&f", "sB1&s", "sB1&v", "sB1,1", + "sB1,f", "sB1,n", "sB1,s", "sB1,v", - "sB1Uk", + "sB1UE", "sB1c", "sB1k1", + "sB1kf", "sB1ks", "sB1kv", + "sB1of", "sB1os", "sB1ov", + "sBE((", + "sBE(1", + "sBE(f", + "sBE(s", + "sBE(v", + "sBf((", "sBf(1", "sBf(f", "sBf(s", "sBf(v", - "sBk(1", - "sBk(s", - "sBk(v", "sBn,n", "sBnk1", + "sBnkf", "sBnks", "sBnkv", "sBs", + "sBs&1", + "sBs&f", "sBs&s", "sBs&v", "sBs,1", + "sBs,f", "sBs,n", "sBs,s", "sBs,v", - "sBsUk", + "sBsUE", "sBsc", "sBsk1", + "sBskf", "sBsks", "sBskv", + "sBso1", + "sBsof", + "sBson", "sBsos", "sBsov", "sBv", + "sBv&1", + "sBv&f", "sBv&s", "sBv&v", "sBv,1", + "sBv,f", "sBv,n", "sBv,s", "sBv,v", - "sBvUk", + "sBvUE", "sBvc", "sBvk1", + "sBvkf", "sBvks", "sBvkv", + "sBvo1", + "sBvof", + "sBvon", "sBvos", "sBvov", - "sU((k", - "sU(k(", - "sU(k1", - "sU(kf", - "sU(kk", - "sU(kn", - "sU(ks", - "sU(kv", + "sE1c", + "sE1of", + "sE1os", + "sE1ov", + "sEU1,", + "sEU1o", + "sEUEf", + "sEUf(", + "sEUs,", + "sEUso", + "sEUv,", + "sEUvo", + "sEf((", + "sEf(1", + "sEf(f", + "sEf(s", + "sEf(v", + "sEnEn", + "sEokn", + "sEsc", + "sEso1", + "sEsof", + "sEson", + "sEsos", + "sEsov", + "sEvc", + "sEvo1", + "sEvof", + "sEvon", + "sEvos", + "sEvov", + "sU", + "sU(((", + "sU((E", + "sU(E(", + "sU(E1", + "sU(Ef", + "sU(En", + "sU(Es", + "sU(Ev", "sU1,1", + "sU1,f", "sU1,s", "sU1,v", + "sU1of", + "sU1os", + "sU1ov", + "sUE", + "sUE((", + "sUE(1", + "sUE(E", + "sUE(f", + "sUE(s", + "sUE(v", + "sUE1", + "sUE1&", + "sUE1,", + "sUE1c", + "sUE1f", + "sUE1k", + "sUE1n", + "sUE1o", + "sUEc", + "sUEf", + "sUEf(", + "sUEf,", + "sUEfc", + "sUEk1", + "sUEkf", + "sUEkn", + "sUEks", + "sUEkv", + "sUEn&", + "sUEn,", + "sUEn1", + "sUEnc", + "sUEnf", + "sUEnk", + "sUEno", + "sUEok", + "sUEs", + "sUEs&", + "sUEs,", + "sUEsc", + "sUEsf", + "sUEsk", + "sUEsn", + "sUEso", + "sUEv", + "sUEv&", + "sUEv,", + "sUEvc", + "sUEvf", + "sUEvk", + "sUEvn", + "sUEvo", "sUc", - "sUk", - "sUk(1", - "sUk(k", - "sUk(n", - "sUk(s", - "sUk(v", - "sUk1", - "sUk1&", - "sUk1,", - "sUk1c", - "sUk1f", - "sUk1k", - "sUk1n", - "sUk1o", - "sUkf", - "sUkf(", - "sUkf,", - "sUkk(", - "sUkk,", - "sUkk1", - "sUkkk", - "sUkkn", - "sUkks", - "sUkkv", - "sUkn&", - "sUkn(", - "sUkn,", - "sUkn1", - "sUknc", - "sUknk", - "sUkno", - "sUkns", - "sUknv", - "sUko1", - "sUkok", - "sUkos", - "sUkov", - "sUks", - "sUks&", - "sUks,", - "sUksc", - "sUksf", - "sUksk", - "sUksn", - "sUkso", - "sUkv", - "sUkv&", - "sUkv,", - "sUkvc", - "sUkvf", - "sUkvk", - "sUkvn", - "sUkvo", - "sUn(k", + "sUf((", + "sUf(1", + "sUf(f", + "sUf(s", + "sUf(v", + "sUk((", + "sUk(E", "sUn,1", + "sUn,f", "sUn,s", "sUn,v", "sUn1,", - "sUnk(", - "sUnk1", - "sUnkf", - "sUnks", - "sUnkv", - "sUno1", - "sUnos", - "sUnov", - "sUns,", - "sUnv,", + "sUn1o", + "sUnE1", + "sUnEf", + "sUnEs", + "sUnEv", + "sUnc", + "sUnf(", + "sUo((", + "sUo(E", "sUon1", - "sUons", - "sUonv", + "sUonf", "sUs,1", + "sUs,f", "sUs,s", "sUs,v", + "sUso1", + "sUsof", + "sUson", + "sUsos", + "sUsov", "sUv,1", + "sUv,f", "sUv,s", "sUv,v", + "sUvo1", + "sUvof", + "sUvon", + "sUvos", + "sUvov", "sc", + "sf(((", + "sf(()", + "sf((1", + "sf((f", + "sf((n", + "sf((s", + "sf((v", + "sf())", "sf()k", "sf(1)", + "sf(1o", + "sf(f(", "sf(n,", "sf(s)", + "sf(so", "sf(v)", + "sf(vo", + "sk(((", + "sk((1", + "sk((f", + "sk((s", + "sk((v", + "sk(1)", + "sk(1o", + "sk(f(", + "sk(s)", + "sk(so", + "sk(v)", + "sk(vo", "sk)&(", "sk)&1", "sk)&f", "sk)&s", "sk)&v", - "sk);k", + "sk))&", + "sk)))", + "sk));", + "sk))B", + "sk))E", + "sk))U", + "sk))k", + "sk))o", + "sk);E", "sk)B1", + "sk)Bf", "sk)Bs", "sk)Bv", - "sk)Uk", - "sk)Un", - "sk)k1", - "sk)kk", - "sk)ks", - "sk)kv", - "sk)o(", - "sk)o1", - "sk)of", - "sk)ok", - "sk)os", - "sk)ov", + "sk)E1", + "sk)Ef", + "sk)Es", + "sk)Ev", + "sk)UE", + "sk)oE", + "sk1", + "sk1&(", "sk1&1", + "sk1&f", + "sk1&o", "sk1&s", "sk1&v", + "sk1;E", + "sk1B1", + "sk1Bf", + "sk1Bs", + "sk1Bv", + "sk1E1", + "sk1Ef", + "sk1Es", + "sk1Ev", "sk1U(", - "sk1Uk", + "sk1UE", "sk1c", - "sk1o1", + "sk1oE", + "sk1of", "sk1os", "sk1ov", - "skU1,", - "skUs,", - "skUv,", + "skf((", "skf(1", + "skf(f", "skf(s", "skf(v", - "skk(1", - "skk(s", - "skk(v", - "skks", - "skksc", - "skkv", - "skkvc", - "sknkn", + "sknc", + "sks", + "sks&(", "sks&1", + "sks&f", + "sks&o", "sks&s", "sks&v", + "sks;E", + "sksB1", + "sksBf", + "sksBs", + "sksBv", + "sksE1", + "sksEf", + "sksEs", + "sksEv", "sksU(", - "sksUk", + "sksUE", "sksc", "skso1", + "sksoE", + "sksof", + "skson", "sksos", "sksov", + "skv", + "skv&(", "skv&1", + "skv&f", + "skv&o", "skv&s", "skv&v", + "skv;E", + "skvB1", + "skvBf", + "skvBs", + "skvBv", + "skvE1", + "skvEf", + "skvEs", + "skvEv", "skvU(", - "skvUk", + "skvUE", "skvc", "skvo1", + "skvoE", + "skvof", + "skvon", "skvos", "skvov", "sn&f(", + "sn)))", + "sn))U", + "sn))n", + "sn)UE", "sn,f(", - "snUk1", - "snUkn", - "snUks", - "snUkv", - "snk1c", - "snkf(", - "snksc", - "snkvc", + "sn1", + "sn1c", + "sn1of", + "sn1os", + "sn1ov", + "snE1c", + "snE1o", + "snEf(", + "snEsc", + "snEso", + "snEvc", + "snEvo", + "snU((", + "snU(E", + "snUE1", + "snUEf", + "snUEs", + "snUEv", + "snf((", + "snf(1", + "snf(f", + "snf(s", + "snf(v", + "sno((", + "sno(1", + "sno(f", "sno(s", "sno(v", - "sno1U", + "snof(", "snosU", + "snoso", "snovU", + "snovo", "so(((", "so((1", + "so((E", "so((f", - "so((k", + "so((n", + "so((o", "so((s", "so((v", "so(1)", "so(1o", + "so(E(", + "so(E1", + "so(EE", + "so(Ef", + "so(En", + "so(Es", + "so(Ev", "so(f(", - "so(k(", - "so(k)", - "so(k1", - "so(kc", - "so(kf", - "so(kk", - "so(kn", - "so(ko", - "so(ks", - "so(kv", "so(n)", "so(o1", + "so(of", "so(os", "so(ov", "so(s)", "so(so", "so(v)", "so(vo", + "so1", + "so1&(", "so1&1", + "so1&E", + "so1&U", + "so1&f", + "so1&k", + "so1&n", "so1&o", "so1&s", "so1&v", + "so1((", + "so1(E", + "so1(U", "so1)&", + "so1))", + "so1),", + "so1);", + "so1)B", + "so1)E", + "so1)U", + "so1)k", "so1)o", + "so1,(", + "so1,1", + "so1,f", + "so1,s", + "so1,v", + "so1:n", + "so1;E", + "so1;n", + "so1B1", + "so1BE", "so1Bf", + "so1Bn", + "so1Bs", + "so1Bv", + "so1E1", + "so1EU", + "so1Ef", + "so1En", + "so1Eo", + "so1Es", + "so1Ev", + "so1U", + "so1U(", + "so1U1", + "so1UE", + "so1Uc", + "so1Uf", "so1Uk", + "so1Un", + "so1Uo", + "so1Us", + "so1Uv", "so1c", "so1f(", + "so1k(", + "so1k)", + "so1k1", "so1kf", + "so1kn", + "so1ks", + "so1kv", + "so1n&", + "so1n,", + "so1n1", + "so1nE", + "so1nU", + "so1nf", + "so1no", "so1o(", - "so1o1", + "so1oE", + "so1oU", "so1of", "so1ok", - "so1oo", "so1os", "so1ov", + "so1s1", + "so1s:", + "so1sf", + "so1so", + "so1sv", + "so1v:", + "so1vf", + "so1vo", + "so1vs", + "soE((", + "soE(1", + "soE(f", + "soE(s", + "soE(v", + "soEUE", + "soU((", + "soU(E", + "sof((", "sof()", "sof(1", "sof(f", - "sof(k", - "sof(n", "sof(s", "sof(v", + "sok&1", + "sok&f", "sok&s", "sok&v", + "sok((", "sok(1", - "sok(k", - "sok(o", + "sok(f", "sok(s", "sok(v", - "sok1", - "sok1,", "sok1c", - "sok1k", "sok1o", - "sokUk", - "sokc", "sokf(", - "sokn,", - "soknk", - "soko(", "soko1", - "sokok", + "sokof", "sokos", "sokov", - "soks", - "soks,", "soksc", - "soksk", "sokso", - "sokv", - "sokv,", "sokvc", - "sokvk", "sokvo", + "son&(", + "son&1", + "son&E", + "son&U", + "son&f", + "son&k", + "son&n", + "son&o", + "son&s", + "son&v", + "son((", + "son(E", + "son(U", + "son)&", + "son))", + "son),", + "son);", + "son)B", + "son)E", + "son)U", + "son)k", + "son)o", + "son,(", + "son,1", + "son,f", + "son,s", + "son,v", + "son1:", + "son1f", + "son1o", + "son1s", + "son1v", + "son:n", + "son;E", + "son;n", + "sonB1", + "sonBE", + "sonBf", + "sonBn", + "sonBs", + "sonBv", + "sonE1", + "sonEU", + "sonEf", + "sonEn", + "sonEo", + "sonEs", + "sonEv", + "sonU", + "sonU(", + "sonU1", + "sonUE", + "sonUc", + "sonUf", + "sonUk", + "sonUn", + "sonUo", + "sonUs", + "sonUv", + "sonc", + "sonf(", + "sonk(", + "sonk)", "sonk1", + "sonkf", + "sonkn", "sonks", "sonkv", + "sono(", + "sonoU", + "sonof", + "sonok", "sonos", "sonov", "sos", "sos&(", "sos&1", + "sos&E", + "sos&U", + "sos&f", + "sos&k", + "sos&n", "sos&o", "sos&s", "sos&v", + "sos((", + "sos(E", + "sos(U", "sos)&", + "sos))", + "sos),", + "sos);", + "sos)B", + "sos)E", + "sos)U", + "sos)k", "sos)o", - "sos:o", + "sos,(", + "sos,1", + "sos,f", + "sos,s", + "sos,v", + "sos1:", + "sos1f", + "sos1o", + "sos1s", + "sos1v", + "sos:n", + "sos;E", + "sos;n", + "sosB1", + "sosBE", "sosBf", + "sosBn", + "sosBs", + "sosBv", + "sosE1", + "sosEU", + "sosEf", + "sosEn", + "sosEo", + "sosEs", + "sosEv", + "sosU", + "sosU(", + "sosU1", + "sosUE", + "sosUc", + "sosUf", "sosUk", + "sosUn", + "sosUo", + "sosUs", + "sosUv", "sosc", "sosf(", + "sosk(", + "sosk)", + "sosk1", "soskf", + "soskn", + "sosks", + "soskv", + "sosn&", + "sosn)", + "sosn,", + "sosn1", + "sosnE", + "sosnU", + "sosnf", + "sosno", "soso(", "soso1", + "sosoE", + "sosoU", "sosof", "sosok", - "sosoo", + "soson", "sosos", "sosov", + "sosv:", + "sosvf", "sosvo", + "sosvs", "sov", "sov&(", "sov&1", + "sov&E", + "sov&U", + "sov&f", + "sov&k", + "sov&n", "sov&o", "sov&s", "sov&v", + "sov((", + "sov(E", + "sov(U", "sov)&", + "sov))", + "sov),", + "sov);", + "sov)B", + "sov)E", + "sov)U", + "sov)k", "sov)o", - "sov:o", + "sov,(", + "sov,1", + "sov,f", + "sov,s", + "sov,v", + "sov:n", + "sov;E", + "sov;n", + "sovB1", + "sovBE", "sovBf", + "sovBn", + "sovBs", + "sovBv", + "sovE1", + "sovEU", + "sovEf", + "sovEn", + "sovEo", + "sovEs", + "sovEv", + "sovU", + "sovU(", + "sovU1", + "sovUE", + "sovUc", + "sovUf", "sovUk", + "sovUn", + "sovUo", + "sovUs", + "sovUv", "sovc", "sovf(", + "sovk(", + "sovk)", + "sovk1", "sovkf", + "sovkn", + "sovks", + "sovkv", + "sovn&", + "sovn)", + "sovn,", + "sovn1", + "sovnE", + "sovnU", + "sovnf", + "sovno", "sovo(", "sovo1", + "sovoE", + "sovoU", "sovof", "sovok", - "sovoo", + "sovon", "sovos", "sovov", + "sovs1", + "sovs:", + "sovsf", "sovso", - "sovvo", + "sovsv", + "sv:1:", + "sv:1o", + "sv:f(", + "sv:s:", + "sv:so", + "sv:v:", + "sv:vo", + "svf((", + "svf(1", + "svf(f", + "svf(s", + "svf(v", + "svo1f", + "svo1o", + "svo1s", + "svo1v", + "svof(", + "svon1", + "svonf", + "svos1", + "svosf", + "svoso", + "svosv", + "svovf", + "svovo", + "svovs", + "svs", + "svsc", + "svso1", + "svsof", + "svson", + "svsos", + "svsov", + "v&(((", + "v&((1", + "v&((E", "v&((f", - "v&((k", + "v&((s", + "v&((v", "v&(1)", "v&(1,", "v&(1o", + "v&(E1", + "v&(Ef", + "v&(Ek", + "v&(En", + "v&(Eo", + "v&(Es", + "v&(Ev", "v&(f(", - "v&(k(", - "v&(k)", - "v&(k1", - "v&(kc", - "v&(kf", - "v&(kk", - "v&(kn", - "v&(ko", - "v&(ks", - "v&(kv", "v&(s)", "v&(s,", "v&(so", @@ -2661,123 +4556,205 @@ static const char* sql_fingerprints[] = { "v&(v,", "v&(vo", "v&1", + "v&1&(", + "v&1&1", + "v&1&f", + "v&1&n", + "v&1&s", + "v&1&v", + "v&1B1", "v&1Bf", - "v&1Uk", + "v&1Bs", + "v&1Bv", + "v&1En", + "v&1U", + "v&1U(", + "v&1UE", + "v&1Uc", "v&1c", "v&1f(", + "v&1k1", + "v&1kf", + "v&1ks", + "v&1kv", "v&1o(", - "v&1o1", + "v&1oE", "v&1of", - "v&1ok", - "v&1on", "v&1oo", "v&1os", "v&1ov", + "v&1so", + "v&1vo", + "v&E((", + "v&E(1", + "v&E(f", + "v&E(o", + "v&E(s", + "v&E(v", + "v&E1k", + "v&E1o", + "v&Ef(", + "v&Ek1", + "v&Ekf", + "v&Eks", + "v&Ekv", + "v&Esk", + "v&Eso", + "v&Evk", + "v&Evo", "v&f((", "v&f()", "v&f(1", "v&f(f", - "v&f(k", "v&f(n", "v&f(s", "v&f(v", + "v&k&1", + "v&k&f", "v&k&s", "v&k&v", - "v&k(1", - "v&k(f", - "v&k(o", - "v&k(s", - "v&k(v", - "v&k1k", "v&k1o", - "v&kUk", - "v&kc", - "v&kk1", - "v&kks", - "v&kkv", + "v&kf(", "v&knk", "v&ko(", "v&ko1", + "v&kof", "v&kok", + "v&kon", "v&kos", "v&kov", - "v&ksk", "v&kso", - "v&kvk", "v&kvo", + "v&n", + "v&n&1", + "v&n&f", + "v&n&n", "v&n&s", "v&n&v", - "v&n()", - "v&no1", + "v&nc", + "v&nk1", + "v&nkf", + "v&nks", + "v&nkv", + "v&nof", "v&nos", "v&nov", + "v&o((", "v&o(1", - "v&o(k", + "v&o(f", "v&o(s", "v&o(v", + "v&o1", + "v&o1c", "v&o1o", - "v&okc", + "v&of(", "v&oko", "v&os", + "v&osc", "v&oso", "v&ov", + "v&ovc", "v&ovo", "v&s", - "v&s:o", + "v&s&(", + "v&s&1", + "v&s&f", + "v&s&n", + "v&s&s", + "v&s&v", + "v&s1o", + "v&sB1", "v&sBf", + "v&sBs", + "v&sBv", + "v&sEn", + "v&sU", "v&sU(", - "v&sUk", + "v&sUE", + "v&sUc", "v&sc", "v&sf(", + "v&sk1", + "v&skf", + "v&sks", + "v&skv", "v&so(", "v&so1", + "v&soE", "v&sof", - "v&sok", "v&son", "v&soo", "v&sos", "v&sov", "v&svo", "v&v", - "v&v:o", + "v&v&(", + "v&v&1", + "v&v&f", + "v&v&n", + "v&v&s", + "v&v&v", + "v&vB1", "v&vBf", + "v&vBs", + "v&vBv", + "v&vEn", + "v&vU", "v&vU(", - "v&vUk", + "v&vUE", + "v&vUc", "v&vc", "v&vf(", + "v&vk1", + "v&vkf", + "v&vks", + "v&vkv", "v&vo(", "v&vo1", + "v&voE", "v&vof", - "v&vok", "v&von", "v&voo", "v&vos", "v&vov", "v&vso", - "v&vvo", - "v(c", + "v((((", + "v(((E", + "v(((U", + "v((En", + "v((U(", + "v(Enk", + "v(U((", + "v(U(E", + "v)&((", "v)&(1", + "v)&(E", "v)&(f", - "v)&(k", - "v)&(n", "v)&(s", "v)&(v", + "v)&1", + "v)&1&", "v)&1B", "v)&1U", + "v)&1c", "v)&1f", "v)&1o", "v)&f(", "v)&o(", + "v)&s", + "v)&s&", "v)&sB", "v)&sU", + "v)&sc", "v)&sf", "v)&so", + "v)&v", + "v)&v&", "v)&vB", "v)&vU", + "v)&vc", "v)&vf", "v)&vo", - "v)()s", - "v)()v", "v))&(", "v))&1", "v))&f", @@ -2787,45 +4764,54 @@ static const char* sql_fingerprints[] = { "v))&v", "v)))&", "v))))", + "v))),", "v)));", "v)))B", + "v)))E", "v)))U", - "v)))c", "v)))k", "v)))o", - "v));c", - "v));k", + "v)),(", + "v));E", "v))B1", + "v))Bf", "v))Bs", "v))Bv", - "v))Uk", - "v))Un", - "v))c", + "v))E1", + "v))Ef", + "v))Es", + "v))Ev", + "v))U(", + "v))UE", "v))k1", - "v))kk", + "v))kf", + "v))kn", "v))ks", "v))kv", "v))o(", "v))o1", + "v))oE", "v))of", - "v))ok", "v))on", "v))os", "v))ov", + "v),((", "v),(1", + "v),(f", "v),(s", "v),(v", - "v);c", - "v);k&", - "v);k(", - "v);kf", - "v);kk", - "v);kn", - "v);ko", + "v);E&", + "v);E(", + "v);E1", + "v);Ef", + "v);Eo", + "v);Es", + "v);Ev", "v)B1", "v)B1&", "v)B1c", "v)B1o", + "v)Bf(", "v)Bs", "v)Bs&", "v)Bsc", @@ -2834,490 +4820,938 @@ static const char* sql_fingerprints[] = { "v)Bv&", "v)Bvc", "v)Bvo", - "v)U(k", - "v)Uk(", - "v)Uk1", - "v)Ukf", - "v)Ukk", - "v)Ukn", - "v)Uko", - "v)Uks", - "v)Ukv", - "v)Unk", - "v)c", - "v)k1", - "v)k1c", + "v)E1c", + "v)E1o", + "v)Ef(", + "v)Esc", + "v)Eso", + "v)Evc", + "v)Evo", + "v)U((", + "v)U(E", + "v)UE(", + "v)UE1", + "v)UEf", + "v)UEk", + "v)UEn", + "v)UEs", + "v)UEv", + "v)k1&", + "v)k1;", + "v)k1B", + "v)k1E", + "v)k1U", "v)k1o", - "v)kks", - "v)kkv", + "v)kf(", "v)knk", - "v)ks", - "v)ksc", + "v)ks&", + "v)ks;", + "v)ksB", + "v)ksE", + "v)ksU", "v)kso", - "v)kv", - "v)kvc", + "v)kv&", + "v)kv;", + "v)kvB", + "v)kvE", + "v)kvU", "v)kvo", - "v)o(1", - "v)o(k", + "v)o((", "v)o(n", - "v)o(s", - "v)o(v", + "v)o1", "v)o1)", - "v)o1B", "v)o1U", - "v)o1f", - "v)o1k", + "v)o1c", "v)o1o", + "v)oE(", "v)of(", - "v)ok(", - "v)ok1", - "v)oks", - "v)okv", + "v)on", "v)on&", + "v)onc", + "v)os", "v)os)", - "v)osB", "v)osU", - "v)osf", - "v)osk", + "v)osc", "v)oso", + "v)ov", "v)ov)", - "v)ovB", "v)ovU", - "v)ovf", - "v)ovk", + "v)ovc", "v)ovo", + "v,(((", + "v,((E", + "v,((f", + "v,(E(", + "v,(E1", + "v,(Ef", + "v,(Es", + "v,(Ev", "v,(f(", - "v,(k(", - "v,(k1", - "v,(kf", - "v,(ks", - "v,(kv", + "v,1))", "v,1),", "v,1)o", "v,1B1", + "v,1Bf", "v,1Bs", "v,1Bv", - "v,1Uk", + "v,1UE", + "v,1of", + "v,1os", + "v,1ov", + "v,f((", "v,f(1", + "v,f(f", "v,f(s", "v,f(v", + "v,s))", "v,s),", "v,s)o", "v,sB1", + "v,sBf", "v,sBs", "v,sBv", - "v,sUk", + "v,sUE", + "v,so1", + "v,sof", + "v,son", + "v,sos", + "v,sov", + "v,v))", "v,v),", "v,v)o", "v,vB1", + "v,vBf", "v,vBs", "v,vBv", - "v,vUk", - "v:o1)", - "v:os)", - "v:ov)", - "v;c", - "v;k&k", - "v;k((", - "v;k(1", - "v;k(o", - "v;k(s", - "v;k(v", - "v;k1,", - "v;k1o", - "v;k;", - "v;k[k", - "v;k[n", - "v;kf(", - "v;kkn", - "v;kks", - "v;kkv", - "v;kn(", - "v;kn,", - "v;knc", - "v;knk", - "v;knn", - "v;ko(", - "v;kok", - "v;ks,", - "v;ksc", - "v;ksk", - "v;kso", - "v;kv,", - "v;kvc", - "v;kvk", - "v;kvo", + "v,vUE", + "v,vo1", + "v,vof", + "v,von", + "v,vos", + "v,vov", + "v:n:1", + "v:n:f", + "v:n:s", + "v:n:v", + "v;E&k", + "v;E((", + "v;E(1", + "v;E(E", + "v;E(f", + "v;E(s", + "v;E(v", + "v;E1,", + "v;E1;", + "v;E1E", + "v;E1c", + "v;E1o", + "v;E;", + "v;E;c", + "v;EEn", + "v;Ef(", + "v;En,", + "v;EnE", + "v;Enc", + "v;Enk", + "v;Eo(", + "v;Es,", + "v;Es;", + "v;EsE", + "v;Esc", + "v;Eso", + "v;Ev,", + "v;Ev;", + "v;EvE", + "v;Evc", + "v;Evo", "v;n:k", "vB1", + "vB1&1", + "vB1&f", "vB1&s", "vB1&v", "vB1,1", + "vB1,f", "vB1,n", "vB1,s", "vB1,v", - "vB1Uk", + "vB1UE", "vB1c", "vB1k1", + "vB1kf", "vB1ks", "vB1kv", + "vB1of", "vB1os", "vB1ov", + "vBE((", + "vBE(1", + "vBE(f", + "vBE(s", + "vBE(v", + "vBf((", "vBf(1", "vBf(f", "vBf(s", "vBf(v", - "vBk(1", - "vBk(s", - "vBk(v", "vBn,n", "vBnk1", + "vBnkf", "vBnks", "vBnkv", "vBs", + "vBs&1", + "vBs&f", "vBs&s", "vBs&v", "vBs,1", + "vBs,f", "vBs,n", "vBs,s", "vBs,v", - "vBsUk", + "vBsUE", "vBsc", "vBsk1", + "vBskf", "vBsks", "vBskv", + "vBso1", + "vBsof", + "vBson", "vBsos", "vBsov", "vBv", + "vBv&1", + "vBv&f", "vBv&s", "vBv&v", "vBv,1", + "vBv,f", "vBv,n", "vBv,s", "vBv,v", - "vBvUk", + "vBvUE", "vBvc", "vBvk1", + "vBvkf", "vBvks", "vBvkv", + "vBvo1", + "vBvof", + "vBvon", "vBvos", "vBvov", + "vE1c", + "vE1of", + "vE1os", + "vE1ov", + "vEU1,", + "vEU1o", + "vEUEf", + "vEUf(", + "vEUs,", + "vEUso", + "vEUv,", + "vEUvo", + "vEf((", + "vEf(1", + "vEf(f", + "vEf(s", + "vEf(v", + "vEnEn", + "vEokn", + "vEsc", + "vEso1", + "vEsof", + "vEson", + "vEsos", + "vEsov", + "vEvc", + "vEvo1", + "vEvof", + "vEvon", + "vEvos", + "vEvov", "vU", - "vU((k", - "vU(k(", - "vU(k1", - "vU(kf", - "vU(kk", - "vU(kn", - "vU(ks", - "vU(kv", + "vU(((", + "vU((E", + "vU(E(", + "vU(E1", + "vU(Ef", + "vU(En", + "vU(Es", + "vU(Ev", "vU1,1", + "vU1,f", "vU1,s", "vU1,v", + "vU1of", + "vU1os", + "vU1ov", + "vUE", + "vUE((", + "vUE(1", + "vUE(E", + "vUE(f", + "vUE(s", + "vUE(v", + "vUE1", + "vUE1&", + "vUE1,", + "vUE1c", + "vUE1f", + "vUE1k", + "vUE1n", + "vUE1o", + "vUEc", + "vUEf", + "vUEf(", + "vUEf,", + "vUEfc", + "vUEk1", + "vUEkf", + "vUEkn", + "vUEks", + "vUEkv", + "vUEn&", + "vUEn,", + "vUEn1", + "vUEnc", + "vUEnf", + "vUEnk", + "vUEno", + "vUEok", + "vUEs", + "vUEs&", + "vUEs,", + "vUEsc", + "vUEsf", + "vUEsk", + "vUEsn", + "vUEso", + "vUEv", + "vUEv&", + "vUEv,", + "vUEvc", + "vUEvf", + "vUEvk", + "vUEvn", + "vUEvo", "vUc", - "vUk", - "vUk(1", - "vUk(k", - "vUk(n", - "vUk(s", - "vUk(v", - "vUk1", - "vUk1&", - "vUk1,", - "vUk1c", - "vUk1f", - "vUk1k", - "vUk1n", - "vUk1o", - "vUkf", - "vUkf(", - "vUkf,", - "vUkk(", - "vUkk,", - "vUkk1", - "vUkkk", - "vUkkn", - "vUkks", - "vUkkv", - "vUkn&", - "vUkn(", - "vUkn,", - "vUkn1", - "vUknc", - "vUknk", - "vUkno", - "vUkns", - "vUknv", - "vUko1", - "vUkok", - "vUkos", - "vUkov", - "vUks", - "vUks&", - "vUks,", - "vUksc", - "vUksf", - "vUksk", - "vUksn", - "vUkso", - "vUkv", - "vUkv&", - "vUkv,", - "vUkvc", - "vUkvf", - "vUkvk", - "vUkvn", - "vUkvo", - "vUn(k", + "vUf((", + "vUf(1", + "vUf(f", + "vUf(s", + "vUf(v", + "vUk((", + "vUk(E", "vUn,1", + "vUn,f", "vUn,s", "vUn,v", "vUn1,", - "vUnk(", - "vUnk1", - "vUnkf", - "vUnks", - "vUnkv", - "vUno1", - "vUnos", - "vUnov", - "vUns,", - "vUnv,", + "vUn1o", + "vUnE1", + "vUnEf", + "vUnEs", + "vUnEv", + "vUnc", + "vUnf(", + "vUo((", + "vUo(E", "vUon1", - "vUons", - "vUonv", + "vUonf", "vUs,1", + "vUs,f", "vUs,s", "vUs,v", + "vUso1", + "vUsof", + "vUson", + "vUsos", + "vUsov", "vUv,1", + "vUv,f", "vUv,s", "vUv,v", + "vUvo1", + "vUvof", + "vUvon", + "vUvos", + "vUvov", "vc", + "vf(((", + "vf(()", + "vf((1", + "vf((f", + "vf((n", + "vf((s", + "vf((v", + "vf())", "vf()k", "vf(1)", + "vf(1o", + "vf(f(", "vf(n,", "vf(s)", + "vf(so", "vf(v)", + "vf(vo", + "vk(((", + "vk((1", + "vk((f", + "vk((s", + "vk((v", + "vk(1)", + "vk(1o", + "vk(f(", + "vk(s)", + "vk(so", + "vk(v)", + "vk(vo", "vk)&(", "vk)&1", "vk)&f", "vk)&s", "vk)&v", - "vk);k", + "vk))&", + "vk)))", + "vk));", + "vk))B", + "vk))E", + "vk))U", + "vk))k", + "vk))o", + "vk);E", "vk)B1", + "vk)Bf", "vk)Bs", "vk)Bv", - "vk)Uk", - "vk)Un", - "vk)k1", - "vk)kk", - "vk)ks", - "vk)kv", - "vk)o(", - "vk)o1", - "vk)of", - "vk)ok", - "vk)os", - "vk)ov", + "vk)E1", + "vk)Ef", + "vk)Es", + "vk)Ev", + "vk)UE", + "vk)oE", + "vk1", + "vk1&(", "vk1&1", + "vk1&f", + "vk1&o", "vk1&s", "vk1&v", + "vk1;E", + "vk1B1", + "vk1Bf", + "vk1Bs", + "vk1Bv", + "vk1E1", + "vk1Ef", + "vk1Es", + "vk1Ev", "vk1U(", - "vk1Uk", + "vk1UE", "vk1c", - "vk1o1", + "vk1oE", + "vk1of", "vk1os", "vk1ov", - "vkU1,", - "vkUs,", - "vkUv,", + "vkf((", "vkf(1", + "vkf(f", "vkf(s", "vkf(v", - "vkk(1", - "vkk(s", - "vkk(v", - "vkks", - "vkksc", - "vkkv", - "vkkvc", - "vknkn", - "vkno1", - "vknov", - "vkokn", + "vknc", + "vks", + "vks&(", "vks&1", + "vks&f", + "vks&o", "vks&s", "vks&v", + "vks;E", + "vksB1", + "vksBf", + "vksBs", + "vksBv", + "vksE1", + "vksEf", + "vksEs", + "vksEv", "vksU(", - "vksUk", + "vksUE", "vksc", "vkso1", + "vksoE", + "vksof", + "vkson", "vksos", "vksov", + "vkv", + "vkv&(", "vkv&1", + "vkv&f", + "vkv&o", "vkv&s", "vkv&v", + "vkv;E", + "vkvB1", + "vkvBf", + "vkvBs", + "vkvBv", + "vkvE1", + "vkvEf", + "vkvEs", + "vkvEv", "vkvU(", - "vkvUk", + "vkvUE", "vkvc", "vkvo1", + "vkvoE", + "vkvof", + "vkvon", "vkvos", "vkvov", "vn&f(", - "vn)Uk", + "vn)))", + "vn))U", + "vn))n", + "vn)UE", "vn,f(", - "vnUk1", - "vnUkn", - "vnUks", - "vnUkv", - "vnk1c", - "vnkf(", - "vnksc", - "vnkvc", + "vn1", + "vn1c", + "vn1of", + "vn1os", + "vn1ov", + "vnE1c", + "vnE1o", + "vnEf(", + "vnEsc", + "vnEso", + "vnEvc", + "vnEvo", + "vnU((", + "vnU(E", + "vnUE1", + "vnUEf", + "vnUEs", + "vnUEv", + "vnf((", + "vnf(1", + "vnf(f", + "vnf(s", + "vnf(v", + "vno((", + "vno(1", + "vno(f", "vno(s", "vno(v", - "vno1U", + "vnof(", "vnosU", + "vnoso", "vnovU", + "vnovo", "vo(((", "vo((1", + "vo((E", "vo((f", - "vo((k", + "vo((n", + "vo((o", "vo((s", "vo((v", "vo(1)", "vo(1o", + "vo(E(", + "vo(E1", + "vo(EE", + "vo(Ef", + "vo(En", + "vo(Es", + "vo(Ev", "vo(f(", - "vo(k(", - "vo(k)", - "vo(k1", - "vo(kc", - "vo(kf", - "vo(kk", - "vo(kn", - "vo(ko", - "vo(ks", - "vo(kv", "vo(n)", "vo(o1", + "vo(of", "vo(os", "vo(ov", "vo(s)", "vo(so", "vo(v)", "vo(vo", + "vo1", + "vo1&(", "vo1&1", + "vo1&E", + "vo1&U", + "vo1&f", + "vo1&k", + "vo1&n", "vo1&o", "vo1&s", "vo1&v", + "vo1((", + "vo1(E", + "vo1(U", "vo1)&", + "vo1))", + "vo1),", + "vo1);", + "vo1)B", + "vo1)E", + "vo1)U", + "vo1)k", "vo1)o", + "vo1,(", + "vo1,1", + "vo1,f", + "vo1,s", + "vo1,v", + "vo1:n", + "vo1;E", + "vo1;n", + "vo1B1", + "vo1BE", "vo1Bf", + "vo1Bn", + "vo1Bs", + "vo1Bv", + "vo1E1", + "vo1EU", + "vo1Ef", + "vo1En", + "vo1Eo", + "vo1Es", + "vo1Ev", + "vo1U", + "vo1U(", + "vo1U1", + "vo1UE", + "vo1Uc", + "vo1Uf", "vo1Uk", + "vo1Un", + "vo1Uo", + "vo1Us", + "vo1Uv", "vo1c", "vo1f(", + "vo1k(", + "vo1k)", + "vo1k1", "vo1kf", + "vo1kn", + "vo1ks", + "vo1kv", + "vo1n&", + "vo1n)", + "vo1n,", + "vo1n1", + "vo1nE", + "vo1nU", + "vo1nf", + "vo1no", "vo1o(", - "vo1o1", + "vo1oE", + "vo1oU", "vo1of", "vo1ok", - "vo1oo", "vo1os", "vo1ov", + "vo1s1", + "vo1s:", + "vo1sf", + "vo1so", + "vo1sv", + "vo1v:", + "vo1vf", + "vo1vo", + "vo1vs", + "voE((", + "voE(1", + "voE(f", + "voE(s", + "voE(v", + "voEUE", + "voU((", + "voU(E", + "vof((", "vof()", "vof(1", "vof(f", - "vof(k", - "vof(n", "vof(s", "vof(v", + "vok&1", + "vok&f", "vok&s", "vok&v", + "vok((", "vok(1", - "vok(k", - "vok(o", + "vok(f", "vok(s", "vok(v", - "vok)U", - "vok)o", - "vok1", - "vok1,", "vok1c", - "vok1k", "vok1o", - "vokUk", - "vokc", "vokf(", - "vokn,", - "voknk", - "voko(", "voko1", - "vokok", + "vokof", "vokos", "vokov", - "voks", - "voks,", "voksc", - "voksk", "vokso", - "vokv", - "vokv,", "vokvc", - "vokvk", "vokvo", + "von&(", + "von&1", + "von&E", + "von&U", + "von&f", + "von&k", + "von&n", + "von&o", + "von&s", + "von&v", + "von((", + "von(E", + "von(U", + "von)&", + "von))", + "von),", + "von);", + "von)B", + "von)E", + "von)U", + "von)k", + "von)o", + "von,(", + "von,1", + "von,f", + "von,s", + "von,v", + "von1:", + "von1f", + "von1o", + "von1s", + "von1v", + "von:n", + "von;E", + "von;n", + "vonB1", + "vonBE", + "vonBf", + "vonBn", + "vonBs", + "vonBv", + "vonE1", + "vonEU", + "vonEf", + "vonEn", + "vonEo", + "vonEs", + "vonEv", + "vonU", + "vonU(", + "vonU1", + "vonUE", + "vonUc", + "vonUf", + "vonUk", + "vonUn", + "vonUo", + "vonUs", + "vonUv", + "vonc", + "vonf(", + "vonk(", + "vonk)", "vonk1", + "vonkf", + "vonkn", "vonks", "vonkv", - "vono1", + "vono(", + "vonoE", + "vonoU", + "vonof", + "vonok", "vonos", "vonov", "vos", "vos&(", "vos&1", + "vos&E", + "vos&U", + "vos&f", + "vos&k", + "vos&n", "vos&o", "vos&s", "vos&v", + "vos((", + "vos(E", + "vos(U", "vos)&", + "vos))", + "vos),", + "vos);", + "vos)B", + "vos)E", "vos)U", + "vos)k", "vos)o", - "vos:o", + "vos,(", + "vos,1", + "vos,f", + "vos,s", + "vos,v", + "vos1:", + "vos1f", + "vos1o", + "vos1s", + "vos1v", + "vos:n", + "vos;E", + "vos;n", + "vosB1", + "vosBE", "vosBf", + "vosBn", + "vosBs", + "vosBv", + "vosE1", + "vosEU", + "vosEf", + "vosEn", + "vosEo", + "vosEs", + "vosEv", + "vosU", + "vosU(", + "vosU1", + "vosUE", + "vosUc", + "vosUf", "vosUk", + "vosUn", + "vosUo", + "vosUs", + "vosUv", "vosc", "vosf(", + "vosk(", + "vosk)", + "vosk1", "voskf", + "voskn", + "vosks", + "voskv", + "vosn&", + "vosn)", + "vosn,", + "vosn1", + "vosnE", + "vosnU", + "vosnf", + "vosno", "voso(", "voso1", + "vosoE", + "vosoU", "vosof", "vosok", - "vosoo", + "voson", "vosos", "vosov", + "vosv:", + "vosvf", "vosvo", + "vosvs", "vov", "vov&(", "vov&1", + "vov&E", + "vov&U", + "vov&f", + "vov&k", + "vov&n", "vov&o", "vov&s", "vov&v", + "vov((", + "vov(E", + "vov(U", "vov)&", + "vov))", + "vov),", + "vov);", + "vov)B", + "vov)E", "vov)U", + "vov)k", "vov)o", - "vov:o", + "vov,(", + "vov,1", + "vov,f", + "vov,s", + "vov,v", + "vov:n", + "vov;E", + "vov;n", + "vovB1", + "vovBE", "vovBf", + "vovBn", + "vovBs", + "vovBv", + "vovE1", + "vovEU", + "vovEf", + "vovEn", + "vovEo", + "vovEs", + "vovEv", + "vovU", + "vovU(", + "vovU1", + "vovUE", + "vovUc", + "vovUf", "vovUk", + "vovUn", + "vovUo", + "vovUs", + "vovUv", "vovc", "vovf(", + "vovk(", + "vovk)", + "vovk1", "vovkf", + "vovkn", + "vovks", + "vovkv", + "vovn&", + "vovn)", + "vovn,", + "vovn1", + "vovnE", + "vovnU", + "vovnf", + "vovno", "vovo(", "vovo1", + "vovoE", + "vovoU", "vovof", "vovok", - "vovoo", + "vovon", "vovos", "vovov", + "vovs1", + "vovs:", + "vovsf", "vovso", - "vovvo", + "vovsv", }; -static const size_t sqli_fingerprints_sz = 2298; +static const size_t sqli_fingerprints_sz = 4719; #endif