diff --git a/CHANGES b/CHANGES index 2b58d703..2fd265d4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,56 @@ +23 Jul 2013 - 2.7.5 +------------------- +Improvements: + + * SecUnicodeCodePage is deprecated. SecUnicodeMapFile now accepts the code page as a second parameter. + + * Updated Libinjection to version 3.4.1. Many improvements were made. + + * Severity action now supports strings (emergency, alert, critical, error, warning, notice, info, debug). + +Bug Fixes: + + * Fixed utf8toUnicode tfn null byte conversion. + + * Fixed NGINX crash when issue reload command. + + * Fixed flush output buffer before inject modified hashed response body. + + * Fixed url normalization for Hash Engine. + + * Fixed NGINX ap_unixd_set_global_perms_mutex compilation error with apache 2.4 devel files. + +Security Issues: + +10 May 2013 - 2.7.4 +------------------- +Improvements: + + * Added Libinjection project http://www.client9.com/projects/libinjection/ as a new operator @detectSQLi. (Thanks Nick Galbreath). + + * Added new variable SDBM_DELETE_ERROR that will be set to 1 when sdbm engine fails to delete entries. + + * NGINX is now set to STABLE. Thanks chaizhenhua and all the people in community who help the project testing, sending feedback and patches. + +Bug Fixes: + + * Fixed SecRulePerfTime storing unnecessary rules performance times. + + * Fixed Possible SDBM deadlock condition. + + * Fixed Possible @rsub memory leak. + + * Fixed REMOTE_ADDR content will receive the client ip address when mod_remoteip.c is present. + + * Fixed NGINX Audit engine in Concurrent mode was overwriting existing alert files because a issue with UNIQUE_ID. + + * Fixed CPU 100% issue in NGINX port. This is also related to an memory leak when loading response body. + +Security Issues: + + * Fixed Remote Null Pointer DeReference (CVE-2013-2765). When forceRequestBodyVariable action is triggered and a unknown Content-Type is used, + mod_security will crash trying to manipulate msr->msc_reqbody_chunks->elts however msr->msc_reqbody_chunks is NULL. (Thanks Younes JAAIDI). + 28 Mar 2013 - 2.7.3 ------------------- @@ -32,7 +85,7 @@ * SECURITY: Added SecXmlExternalEntity (On|Off - default it Off) that will disable by default the external entity load task executed by LibXml2. This is a security issue - reported by Timur Yunusov, Alexey Osipov (Positive Technologies). + [CVE-2013-1915] reported by Timur Yunusov, Alexey Osipov (Positive Technologies). 21 Jan 2013 - 2.7.2 ------------------- @@ -130,7 +183,7 @@ support Include directive like Apache2. * Added MULTIPART_INVALID_PART flag. Also used in rule id 200002 for multipart strict - validation. + validation. https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20121017-0_mod_security_ruleset_bypass.txt). * Updated Reference Manual. diff --git a/NOTICE b/NOTICE index 553a3efc..0501be9f 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ ModSecurity (www.modsecurity.org) -    Copyright [2004-2011] Trustwave Holdings, Inc +    Copyright [2004-2013] Trustwave Holdings, Inc     This product includes software developed at     Trustwave Holdings, Inc (http://www.trustwave.com/). diff --git a/README.TXT b/README.TXT index ff2a0bee..3647d08f 100644 --- a/README.TXT +++ b/README.TXT @@ -1,5 +1,5 @@ ModSecurity for Apache 2.x, http://www.modsecurity.org/ -Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) You may not use this file except in compliance with the License.  You may obtain a copy of the License at diff --git a/alp2/alp2.c b/alp2/alp2.c index fd2d6ba8..8a40272c 100755 --- a/alp2/alp2.c +++ b/alp2/alp2.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2.h b/alp2/alp2.h index 332e3ca3..2a159d56 100644 --- a/alp2/alp2.h +++ b/alp2/alp2.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2_pp.c b/alp2/alp2_pp.c index d88d636c..5649dc18 100755 --- a/alp2/alp2_pp.c +++ b/alp2/alp2_pp.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/alp2/alp2_pp.h b/alp2/alp2_pp.h index 8ccdaeac..ba5c0909 100644 --- a/alp2/alp2_pp.h +++ b/alp2/alp2_pp.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/Makefile.am b/apache2/Makefile.am index 38211f9b..550be2ed 100644 --- a/apache2/Makefile.am +++ b/apache2/Makefile.am @@ -11,7 +11,8 @@ mod_security2_la_SOURCES = mod_security2.c \ re_variables.c msc_logging.c msc_xml.c \ msc_multipart.c modsecurity.c msc_parsers.c \ msc_util.c msc_pcre.c persist_dbm.c msc_reqbody.c \ - msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c + msc_geo.c msc_gsb.c msc_crypt.c msc_tree.c msc_unicode.c acmp.c msc_lua.c msc_release.c \ + libinjection/libinjection_sqli.c mod_security2_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@ @@ -72,7 +73,7 @@ install-exec-hook: $(pkglib_LTLIBRARIES) for m in $(pkglib_LTLIBRARIES); do \ base=`echo $$m | sed 's/\..*//'`; \ rm -f $(DESTDIR)$(pkglibdir)/$$base.*a; \ - install -D -m444 $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES); \ + install -D -m444 $(DESTDIR)$(pkglibdir)/$$base.so $(DESTDIR)$(APXS_MODULES)/$$base.so; \ done else install-exec-hook: $(pkglib_LTLIBRARIES) diff --git a/apache2/Makefile.win b/apache2/Makefile.win index c6c4bb6b..31a83a99 100644 --- a/apache2/Makefile.win +++ b/apache2/Makefile.win @@ -46,7 +46,7 @@ OBJS = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \ msc_logging.obj msc_xml.obj msc_multipart.obj modsecurity.obj \ msc_parsers.obj msc_util.obj msc_pcre.obj persist_dbm.obj \ msc_reqbody.obj msc_geo.obj msc_gsb.obj msc_crypt.obj msc_tree.obj msc_unicode.obj acmp.obj msc_lua.obj \ - msc_release.obj + msc_release.obj libinjection\libinjection_sqli.obj all: $(DLL) diff --git a/apache2/acmp.c b/apache2/acmp.c index 5f55b8e1..6e796b38 100644 --- a/apache2/acmp.c +++ b/apache2/acmp.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/acmp.h b/apache2/acmp.h index bc5f5b2f..65665167 100644 --- a/apache2/acmp.h +++ b/apache2/acmp.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/acmp.obj b/apache2/acmp.obj new file mode 100644 index 00000000..1f2f2e51 Binary files /dev/null and b/apache2/acmp.obj differ diff --git a/apache2/apache2.h b/apache2/apache2.h index c658da34..87a17ed2 100644 --- a/apache2/apache2.h +++ b/apache2/apache2.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c index b7ae56c0..84385f57 100644 --- a/apache2/apache2_config.c +++ b/apache2/apache2_config.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -2346,7 +2346,7 @@ static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1) dcfg->hash_is_enabled = HASH_DISABLED; dcfg->hash_enforcement = HASH_DISABLED; } - else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SexHashEngine: %s", p1); + else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecHashEngine: %s", p1); return NULL; } @@ -2656,6 +2656,8 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg, /** * \brief Add SecUnicodeCodePage configuration option * +* Depcrecated +* * \param cmd Pointer to configuration data * \param _dcfg Pointer to directory configuration * \param p1 Pointer to configuration option @@ -2688,13 +2690,24 @@ static const char *cmd_unicode_codepage(cmd_parms *cmd, * \retval NULL On success */ static const char *cmd_unicode_map(cmd_parms *cmd, void *_dcfg, - const char *p1) + const char *p1, const char *p2) { const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1); char *error_msg; + long val = 0; directory_config *dcfg = (directory_config *)_dcfg; if (dcfg == NULL) return NULL; + if(p2 != NULL) { + val = atol(p2); + if (val <= 0) { + return apr_psprintf(cmd->pool, "ModSecurity: Invalid setting for " + "SecUnicodeMapFile: %s", p2); + } + + unicode_codepage = (unsigned long int)val; + } + if (unicode_map_init(dcfg, filename, &error_msg) <= 0) { return error_msg; } @@ -3069,7 +3082,7 @@ const command_rec module_directives[] = { "Unicode CodePage" ), - AP_INIT_TAKE1 ( + AP_INIT_TAKE12 ( "SecUnicodeMapFile", cmd_unicode_map, NULL, diff --git a/apache2/apache2_config.obj b/apache2/apache2_config.obj new file mode 100644 index 00000000..2d6abca3 Binary files /dev/null and b/apache2/apache2_config.obj differ diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c index e6f28b75..88f19031 100644 --- a/apache2/apache2_io.c +++ b/apache2/apache2_io.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -588,7 +588,7 @@ static int flatten_response_body(modsec_rec *msr) { } memset(msr->stream_output_data, 0, msr->stream_output_length+1); - strncpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length); + memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length); msr->stream_output_data[msr->stream_output_length] = '\0'; } else if (msr->txcfg->stream_outbody_inspection && msr->txcfg->hash_is_enabled == HASH_ENABLED) { int retval = 0; @@ -617,7 +617,7 @@ static int flatten_response_body(modsec_rec *msr) { } memset(msr->stream_output_data, 0, msr->stream_output_length+1); - strncpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length); + memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length); msr->stream_output_data[msr->stream_output_length] = '\0'; } } diff --git a/apache2/apache2_io.obj b/apache2/apache2_io.obj new file mode 100644 index 00000000..d85cfd7e Binary files /dev/null and b/apache2/apache2_io.obj differ diff --git a/apache2/apache2_util.c b/apache2/apache2_util.c index 11879b21..0960dc8e 100644 --- a/apache2/apache2_util.c +++ b/apache2/apache2_util.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -198,6 +198,10 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec * apr_size_t nbytes, nbytes_written; apr_file_t *debuglog_fd = NULL; int filter_debug_level = 0; + char *remote = NULL; + char *parse_remote = NULL; + char *saved = NULL; + char *str = NULL; char str1[1024] = ""; char str2[1256] = ""; @@ -269,8 +273,8 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec * hostname, log_escape(msr->mp, r->uri), unique_id); #else ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server, - "[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->connection->remote_ip, str1, - hostname, log_escape(msr->mp, r->uri), unique_id); + "[client %s] ModSecurity: %s%s [uri \"%s\"]%s", msr->remote_addr ? msr->remote_addr : r->connection->remote_ip, str1, + hostname, log_escape(msr->mp, r->uri), unique_id); #endif /* Add this message to the list. */ diff --git a/apache2/apache2_util.obj b/apache2/apache2_util.obj new file mode 100644 index 00000000..8fbee704 Binary files /dev/null and b/apache2/apache2_util.obj differ diff --git a/apache2/libinjection/COPYING.txt b/apache2/libinjection/COPYING.txt new file mode 100644 index 00000000..ef2f78d7 --- /dev/null +++ b/apache2/libinjection/COPYING.txt @@ -0,0 +1,37 @@ +/* + * Copyright 2012, 2013 + * Nick Galbreath -- nickg [at] client9 [dot] com + * http://www.client9.com/projects/libinjection/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of libinjection nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This is the standard "new" BSD license: + * http://www.opensource.org/licenses/bsd-license.php + */ diff --git a/apache2/libinjection/libinjection.h b/apache2/libinjection/libinjection.h new file mode 100644 index 00000000..4e5690d8 --- /dev/null +++ b/apache2/libinjection/libinjection.h @@ -0,0 +1,286 @@ +/** + * Copyright 2012, 2013 Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * https://libinjection.client9.com/ + * + */ + +#ifndef _LIBINJECTION_H +#define _LIBINJECTION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Version info. + * See python's normalized version + * http://www.python.org/dev/peps/pep-0386/#normalizedversion + */ +#define LIBINJECTION_VERSION "3.4.1" + +/** + * Libinjection's sqli module makes a "normalized" + * value of the token. This is the maximum size + * Token with values larger than this will be truncated + */ +#ifndef LIBINJECTION_SQLI_TOKEN_SIZE +#define LIBINJECTION_SQLI_TOKEN_SIZE 32 +#endif + +/** + * Number of tokens used to create a fingerprint + */ +#ifndef LIBINJECTION_SQLI_MAX_TOKENS +#define LIBINJECTION_SQLI_MAX_TOKENS 5 +#endif + +enum lookup_type { + FLAG_NONE = 0, + FLAG_QUOTE_NONE = 1 << 1, + FLAG_QUOTE_SINGLE = 1 << 2, + FLAG_QUOTE_DOUBLE = 1 << 3, + + FLAG_SQL_ANSI = 1 << 4, + FLAG_SQL_MYSQL = 1 << 5, + + LOOKUP_WORD, + LOOKUP_TYPE, + LOOKUP_OPERATOR, + LOOKUP_FINGERPRINT +}; + +typedef struct { +#ifdef SWIG +%immutable; +#endif + char type; + char str_open; + char str_close; + + /* + * position and length of token + * in original string + */ + size_t pos; + size_t len; + + /* count: + * in type 'v', used for number of opening '@' + * but maybe unsed in other contexts + */ + int count; + + char val[LIBINJECTION_SQLI_TOKEN_SIZE]; +} stoken_t; + + +/** + * Pointer to function, takes cstr input, + * returns '\0' for no match, else a char + */ +struct libinjection_sqli_state; +typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state*, int lookuptype, const char* word, size_t len); + +typedef struct libinjection_sqli_state { +#ifdef SWIG +%immutable; +#endif + + /* + * input, does not need to be null terminated. + * it is also not modified. + */ + const char *s; + + /* + * input length + */ + size_t slen; + + /* + * How to lookup a word or fingerprint + */ + ptr_lookup_fn lookup; + void* userdata; + + /* + * + */ + int flags; + + /* + * pos is index in string we are at when tokenizing + */ + size_t pos; + + /* MAX TOKENS + 1 since we use one extra token + * to determine the type of the previous token + */ + stoken_t tokenvec[LIBINJECTION_SQLI_MAX_TOKENS + 1]; + + /* + * Pointer to token position in tokenvec, above + */ + stoken_t *current; + + /* + * fingerprint pattern c-string + * +1 for ending null + */ + char fingerprint[LIBINJECTION_SQLI_MAX_TOKENS + 1]; + + /* + * Line number of code that said decided if the input was SQLi or + * not. Most of the time it's line that said "it's not a matching + * fingerprint" but there is other logic that sometimes approves + * an input. This is only useful for debugging. + * + */ + int reason; + + /* Number of ddw (dash-dash-white) comments + * These comments are in the form of + * '--[whitespace]' or '--[EOF]' + * + * All databases treat this as a comment. + */ + int stats_comment_ddw; + + /* Number of ddx (dash-dash-[notwhite]) comments + * + * ANSI SQL treats these are comments, MySQL treats this as + * two unary operators '-' '-' + * + * If you are parsing result returns FALSE and + * stats_comment_dd > 0, you should reparse with + * COMMENT_MYSQL + * + */ + int stats_comment_ddx; + + /* + * c-style comments found /x .. x/ + */ + int stats_comment_c; + + /* '#' operators or mysql EOL comments found + * + */ + int stats_comment_hash; + + /* + * number of tokens folded away + */ + int stats_folds; + + /* + * total tokens processed + */ + int stats_tokens; + +} sfilter; + +/** + * + */ +void libinjection_sqli_init(sfilter* sql_state, + const char* s, size_t slen, + int flags); + +/** + * Main API: tests for SQLi in three possible contexts, no quotes, + * single quote and double quote + * + * \param sql_state + * \param s + * \param slen + * \param fn a pointer to a function that determines if a fingerprint + * is a match or not. If NULL, then a hardwired list is + * used. Useful for loading fingerprints data from custom + * sources. + * + * \return 1 (true) if SQLi, 0 (false) if benign + */ +int libinjection_is_sqli(sfilter * sql_state); + +/* FOR H@CKERS ONLY + * + */ +void libinjection_sqli_callback(sfilter* sql_state, ptr_lookup_fn fn, void* userdata); + + +/* + * Resets state, but keeps initial string and callbacks + */ +void libinjection_sqli_reset(sfilter* sql_state, int flags); + +/** + * + */ + +/** + * This detects SQLi in a single context, mostly useful for custom + * logic and debugging. + * + * \param sql_state + * + * \returns a pointer to sfilter.fingerprint as convenience + * do not free! + * + */ +const char* libinjection_sqli_fingerprint(sfilter * sql_state, int flags); + +/** + * The default "word" to token-type or fingerprint function. This + * uses a ASCII case-insensitive binary tree. + */ +char libinjection_sqli_lookup_word(sfilter *sql_state, int lookup_type, + const char* s, size_t slen); + +/* Streaming tokenization interface. + * + * sql_state->current is updated with the current token. + * + * \returns 1, has a token, keep going, or 0 no tokens + * + */ +int libinjection_sqli_tokenize(sfilter * sql_state); + +/** + * parses and folds input, up to 5 tokens + * + */ +int libinjection_sqli_fold(sfilter * sql_state); + +/** The built-in default function to match fingerprints + * and do false negative/positive analysis. This calls the following + * two functions. With this, you over-ride one part or the other. + * + * return libinjection_sqli_blacklist(sql_state) && + * libinject_sqli_not_whitelist(sql_state); + * + * \param sql_state should be filled out after libinjection_sqli_fingerprint is called + */ +int libinjection_sqli_check_fingerprint(sfilter *sql_state); + +/* Given a pattern determine if it's a SQLi pattern. + * + * \return TRUE if sqli, false otherwise + */ +int libinjection_sqli_blacklist(sfilter* sql_state); + +/* Given a positive match for a pattern (i.e. pattern is SQLi), this function + * does additional analysis to reduce false positives. + * + * \return TRUE if sqli, false otherwise + */ +int libinjection_sqli_not_whitelist(sfilter* sql_state); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBINJECTION_H */ diff --git a/apache2/libinjection/libinjection_sqli.c b/apache2/libinjection/libinjection_sqli.c new file mode 100644 index 00000000..3634757f --- /dev/null +++ b/apache2/libinjection/libinjection_sqli.c @@ -0,0 +1,2082 @@ +/** + * Copyright 2012,2013 Nick Galbreath + * nickg@client9.com + * BSD License -- see COPYING.txt for details + * + * https://libinjection.client9.com/ + * + */ + +#include +#include +#include +#include +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define CHAR_NULL '\0' +#define CHAR_SINGLE '\'' +#define CHAR_DOUBLE '"' + +/* faster than calling out to libc isdigit */ +#define ISDIGIT(a) ((unsigned)((a) - '0') <= 9) + +#if 0 +#define FOLD_DEBUG printf("%d \t more=%d pos=%d left=%d\n", __LINE__, more, (int)pos, (int)left); +#else +#define FOLD_DEBUG +#endif + +#include "libinjection_sqli_data.h" + +/* + * not making public just yet + */ +typedef enum { + TYPE_NONE = 0, + TYPE_KEYWORD = (int)'k', + TYPE_UNION = (int)'U', + TYPE_GROUP = (int)'B', + TYPE_EXPRESSION = (int)'E', + TYPE_SQLTYPE = (int)'t', + TYPE_FUNCTION = (int)'f', + TYPE_BAREWORD = (int)'n', + TYPE_NUMBER = (int)'1', + TYPE_VARIABLE = (int)'v', + TYPE_STRING = (int)'s', + TYPE_OPERATOR = (int)'o', + TYPE_LOGIC_OPERATOR = (int)'&', + TYPE_COMMENT = (int)'c', + TYPE_COLLATE = (int)'A', + TYPE_LEFTPARENS = (int)'(', + TYPE_RIGHTPARENS = (int)')', /* not used? */ + TYPE_COMMA = (int)',', + TYPE_COLON = (int)':', + TYPE_SEMICOLON = (int)';', + TYPE_TSQL = (int)'T', /* TSQL start */ + TYPE_UNKNOWN = (int)'?', + TYPE_EVIL = (int)'X', /* unparsable, abort */ + TYPE_FINGERPRINT = (int)'F', /* not really a token */ + TYPE_BACKSLASH = (int)'\\' +} sqli_token_types; + +/** + * Initializes parsing state + * + */ +static char flag2delim(int flag) +{ + if (flag & FLAG_QUOTE_SINGLE) { + return CHAR_SINGLE; + } else if (flag & FLAG_QUOTE_DOUBLE) { + return CHAR_DOUBLE; + } else { + return CHAR_NULL; + } +} + +/* memchr2 finds a string of 2 characters inside another string + * This a specialized version of "memmem" or "memchr". + * 'memmem' doesn't exist on all platforms + * + * Porting notes: this is just a special version of + * astring.find("AB") + * + */ +static const char * +memchr2(const char *haystack, size_t haystack_len, char c0, char c1) +{ + const char *cur = haystack; + const char *last = haystack + haystack_len - 1; + + if (haystack_len < 2) { + return NULL; + } + + while (cur < last) { + if (cur[0] == c0) { + if (cur[1] == c1) { + return cur; + } else { + cur += 2; //(c0 == c1) ? 1 : 2; + } + } else { + cur += 1; + } + } + + return NULL; +} + +/** + */ +static const char * +my_memmem(const char* haystack, size_t hlen, const char* needle, size_t nlen) +{ + const char* cur = NULL; + const char* last = NULL; + + if(nlen < 1 || needle == NULL || haystack == NULL) + return NULL; + + last = haystack + hlen - nlen; + + for (cur = haystack; cur <= last; ++cur) { + if (cur[0] == needle[0] && memcmp(cur, needle, nlen) == 0) { + return cur; + } + } + return NULL; +} +/** Find largest string containing certain characters. + * + * C Standard library 'strspn' only works for 'c-strings' (null terminated) + * This works on arbitrary length. + * + * Performance notes: + * not critical + * + * Porting notes: + * if accept is 'ABC', then this function would be similar to + * a_regexp.match(a_str, '[ABC]*'), + */ +static size_t +strlenspn(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; +} + +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; +} +static int char_is_white(char ch) { + /* ' ' space is 0x32 + '\t 0x09 \011 horizontal tab + '\n' 0x0a \012 new line + '\v' 0x0b \013 verical tab + '\f' 0x0c \014 new page + '\r' 0x0d \015 carriage return + 0x00 \000 null (oracle) + 0xa0 \240 is latin1 + */ + return strchr(" \t\n\v\f\r\240\000", ch) != NULL; +} + +/* DANGER DANGER + * This is -very specialized function- + * + * this compares a ALL_UPPER CASE C STRING + * with a *arbitrary memory* + length + * + * Sane people would just make a copy, up-case + * and use a hash table. + * + * Required since libc version uses the current locale + * and is much slower. + */ +static int cstrcasecmp(const char *a, const char *b, size_t n) +{ + char cb; + + for (; n > 0; a++, b++, n--) { + cb = *b; + if (cb >= 'a' && cb <= 'z') { + cb -= 0x20; + } + if (*a != cb) { + return *a - cb; + } else if (*a == '\0') { + return -1; + } + } + //printf("off the edge\n"); + return (*a == 0) ? 0 : 1; +} + +/** + * Case sensitive string compare. + * Here only to make code more readable + */ +static int streq(const char *a, const char *b) +{ + return strcmp(a, b) == 0; +} + +/** + * + * + * + * Porting Notes: + * given a mapping/hash of string to char + * this is just + * typecode = mapping[key.upper()] + */ + +static char bsearch_keyword_type(const char *key, size_t len, + const keyword_t * keywords, size_t numb) +{ + size_t pos; + size_t left = 0; + size_t right = numb - 1; + + while (left < right) { + pos = (left + right) >> 1; + + /* arg0 = upper case only, arg1 = mixed case */ + if (cstrcasecmp(keywords[pos].word, key, len) < 0) { + left = pos + 1; + } else { + right = pos; + } + } + if ((left == right) && cstrcasecmp(keywords[left].word, key, len) == 0) { + return keywords[left].type; + } else { + return CHAR_NULL; + } +} + +static char is_keyword(const char* key, size_t len) +{ + return bsearch_keyword_type(key, len, sql_keywords, sql_keywords_sz); +} + +/* st_token methods + * + * The following functions manipulates the stoken_t type + * + * + */ + +static void st_clear(stoken_t * st) +{ + memset(st, 0, sizeof(stoken_t)); +} + +static void st_assign_char(stoken_t * st, const char stype, size_t pos, size_t len, + const char value) +{ + st->type = (char) stype; + st->pos = pos; + st->len = len; + st->val[0] = value; + st->val[1] = CHAR_NULL; +} + +static void st_assign(stoken_t * st, const char stype, + size_t pos, size_t len, const char* value) +{ + const size_t MSIZE = LIBINJECTION_SQLI_TOKEN_SIZE; + size_t last = len < MSIZE ? len : (MSIZE - 1); + st->type = (char) stype; + st->pos = pos; + st->len = len; + memcpy(st->val, value, last); + st->val[last] = CHAR_NULL; +} + +static void st_copy(stoken_t * dest, const stoken_t * src) +{ + memcpy(dest, src, sizeof(stoken_t)); +} + +static int st_is_arithmetic_op(const stoken_t* st) +{ + const char ch = st->val[0]; + return (st->type == TYPE_OPERATOR && st->len == 1 && + (ch == '*' || ch == '/' || ch == '-' || ch == '+' || ch == '%')); +} + +static int st_is_unary_op(const stoken_t * st) +{ + const char* str = st->val; + const size_t len = st->len; + + if (st->type != TYPE_OPERATOR) { + return FALSE; + } + + switch (len) { + case 1: + return *str == '+' || *str == '-' || *str == '!' || *str == '~'; + case 2: + return str[0] == '!' && str[1] == '!'; + case 3: + return cstrcasecmp("NOT", str, len) == 0; + default: + return FALSE; + } +} + +/* Parsers + * + * + */ + +static size_t parse_white(sfilter * sf) +{ + return sf->pos + 1; +} + +static size_t parse_operator1(sfilter * sf) +{ + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(sf->current, TYPE_OPERATOR, pos, 1, cs[pos]); + return pos + 1; +} + +static size_t parse_other(sfilter * sf) +{ + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(sf->current, TYPE_UNKNOWN, pos, 1, cs[pos]); + return pos + 1; +} + +static size_t parse_char(sfilter * sf) +{ + const char *cs = sf->s; + size_t pos = sf->pos; + + st_assign_char(sf->current, cs[pos], pos, 1, cs[pos]); + return pos + 1; +} + +static size_t parse_eol_comment(sfilter * sf) +{ + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + const char *endpos = + (const char *) memchr((const void *) (cs + pos), '\n', slen - pos); + if (endpos == NULL) { + st_assign(sf->current, TYPE_COMMENT, pos, slen - pos, cs + pos); + return slen; + } else { + st_assign(sf->current, TYPE_COMMENT, pos, endpos - cs - pos, cs + pos); + return (endpos - cs) + 1; + } +} + +/** In Ansi mode, hash is an operator + * In MYSQL mode, it's a EOL comment like '--' + */ +static size_t parse_hash(sfilter * sf) +{ + sf->stats_comment_hash += 1; + if (sf->flags & FLAG_SQL_MYSQL) { + sf->stats_comment_hash += 1; + return parse_eol_comment(sf); + } else { + st_assign_char(sf->current, TYPE_OPERATOR, sf->pos, 1, '#'); + return sf->pos + 1; + } +} + +static size_t parse_dash(sfilter * sf) +{ + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + /* + * five cases + * 1) --[white] this is always a SQL comment + * 2) --[EOF] this is a comment + * 3) --[notwhite] in MySQL this is NOT a comment but two unary operators + * 4) --[notwhite] everyone else thinks this is a comment + * 5) -[not dash] '-' is a unary operator + */ + + if (pos + 2 < slen && cs[pos + 1] == '-' && char_is_white(cs[pos+2]) ) { + return parse_eol_comment(sf); + } else if (pos +2 == slen && cs[pos + 1] == '-') { + return parse_eol_comment(sf); + } else if (pos + 1 < slen && cs[pos + 1] == '-' && (sf->flags & FLAG_SQL_ANSI)) { + /* --[not-white] not-white case: + * + */ + sf->stats_comment_ddx += 1; + return parse_eol_comment(sf); + } else { + st_assign_char(sf->current, TYPE_OPERATOR, pos, 1, '-'); + return pos + 1; + } +} + + +/** This detects MySQL comments, comments that + * start with /x! We just ban these now but + * previously we attempted to parse the inside + * + * For reference: + * the form of /x![anything]x/ or /x!12345[anything] x/ + * + * Mysql 3 (maybe 4), allowed this: + * /x!0selectx/ 1; + * where 0 could be any number. + * + * The last version of MySQL 3 was in 2003. + + * It is unclear if the MySQL 3 syntax was allowed + * in MySQL 4. The last version of MySQL 4 was in 2008 + * + */ +static size_t is_mysql_comment(const char *cs, const size_t len, size_t pos) +{ + /* so far... + * cs[pos] == '/' && cs[pos+1] == '*' + */ + + if (pos + 2 >= len) { + /* not a mysql comment */ + return 0; + } + + if (cs[pos + 2] != '!') { + /* not a mysql comment */ + return 0; + } + + /* + * this is a mysql comment + * got "/x!" + */ + return 1; +} + +static size_t parse_slash(sfilter * sf) +{ + size_t clen; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + const char* cur = cs + pos; + char ctype = TYPE_COMMENT; + size_t pos1 = pos + 1; + const char *ptr; + if (pos1 == slen || cs[pos1] != '*') { + return parse_operator1(sf); + } + + /* + * skip over initial '/x' + */ + ptr = memchr2(cur + 2, slen - (pos + 2), '*', '/'); + if (ptr == NULL) { + /* till end of line */ + clen = slen - pos; + } else { + clen = (ptr +2) - cur; + } + + /* + * postgresql allows nested comments which makes + * this is incompatible with parsing so + * if we find a '/x' inside the coment, then + * make a new token. + * + * Also, Mysql's "conditional" comments for version + * are an automatic black ban! + */ + + if (memchr2(cur + 2, ptr - (cur + 1), '/', '*') != NULL) { + ctype = TYPE_EVIL; + } else if (is_mysql_comment(cs, slen, pos)) { + ctype = TYPE_EVIL; + } + + st_assign(sf->current, ctype, pos, clen, cs + pos); + return pos + clen; +} + + +static size_t parse_backslash(sfilter * sf) +{ + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + /* + * Weird MySQL alias for NULL, "\N" (capital N only) + */ + if (pos + 1 < slen && cs[pos +1] == 'N') { + st_assign(sf->current, TYPE_NUMBER, pos, 2, cs + pos); + return pos + 2; + } else { + st_assign_char(sf->current, TYPE_BACKSLASH, pos, 1, cs[pos]); + return pos + 1; + } +} + +static size_t parse_operator2(sfilter * sf) +{ + char ch; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 >= slen) { + return parse_operator1(sf); + } + + if (pos + 2 < slen && + cs[pos] == '<' && + cs[pos + 1] == '=' && + cs[pos + 2] == '>') { + /* + * special 3-char operator + */ + st_assign(sf->current, TYPE_OPERATOR, pos, 3, cs + pos); + return pos + 3; + } + + ch = sf->lookup(sf, LOOKUP_OPERATOR, cs + pos, 2); + if (ch != CHAR_NULL) { + st_assign(sf->current, ch, pos, 2, cs+pos); + return pos + 2; + } + + /* + * not an operator.. what to do with the two + * characters we got? + */ + + if (cs[pos] == ':') { + /* ':' is not an operator */ + st_assign(sf->current, TYPE_COLON, pos, 1, cs+pos); + return pos + 1; + } else { + /* + * must be a single char operator + */ + return parse_operator1(sf); + } +} + +/* + * Ok! " \" " one backslash = escaped! + * " \\" " two backslash = not escaped! + * "\\\" " three backslash = escaped! + */ +static int is_backslash_escaped(const char* end, const char* start) +{ + const char* ptr; + for (ptr = end; ptr >= start; ptr--) { + if (*ptr != '\\') { + break; + } + } + /* if number of backslashes is odd, it is escaped */ + + return (end - ptr) & 1; +} + +static size_t is_double_delim_escaped(const char* cur, const char* end) +{ + return ((cur + 1) < end) && *(cur+1) == *cur; +} + +/* Look forward for doubling of deliminter + * + * case 'foo''bar' --> foo''bar + * + * ending quote isn't duplicated (i.e. escaped) + * since it's the wrong char or EOL + * + */ +static size_t parse_string_core(const char *cs, const size_t len, size_t pos, + stoken_t * st, char delim, size_t offset) +{ + /* + * offset is to skip the perhaps first quote char + */ + const char *qpos = + (const char *) memchr((const void *) (cs + pos + offset), delim, + len - pos - offset); + + /* + * then keep string open/close info + */ + if (offset > 0) { + /* + * this is real quote + */ + st->str_open = delim; + } else { + /* + * this was a simulated quote + */ + st->str_open = CHAR_NULL; + } + + while (TRUE) { + if (qpos == NULL) { + /* + * string ended with no trailing quote + * assign what we have + */ + st_assign(st, TYPE_STRING, pos + offset, len - pos - offset, cs + pos + offset); + st->str_close = CHAR_NULL; + return len; + } else if ( is_backslash_escaped(qpos - 1, cs + pos + offset)) { + /* keep going, move ahead one character */ + qpos = + (const char *) memchr((const void *) (qpos + 1), delim, + (cs + len) - (qpos + 1)); + continue; + } else if (is_double_delim_escaped(qpos, cs + len)) { + /* keep going, move ahead two characters */ + qpos = + (const char *) memchr((const void *) (qpos + 2), delim, + (cs + len) - (qpos + 2)); + continue; + } else { + /* hey it's a normal string */ + st_assign(st, TYPE_STRING, pos + offset, + qpos - (cs + pos + offset), cs + pos + offset); + st->str_close = delim; + return qpos - cs + 1; + } + } +} + +/** + * Used when first char is a ' or " + */ +static size_t parse_string(sfilter * sf) +{ + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + /* + * assert cs[pos] == single or double quote + */ + return parse_string_core(cs, slen, pos, sf->current, cs[pos], 1); +} + +/** + * Used when first char is: + * N or n: mysql "National Character set" + * E : psql "Escaped String" + */ +static size_t parse_estring(sfilter * sf) +{ + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 2 >= slen || cs[pos+1] != CHAR_SINGLE) { + return parse_word(sf); + } + return parse_string_core(cs, slen, pos, sf->current, CHAR_SINGLE, 2); +} + +/** MySQL ad-hoc character encoding + * + * if something starts with a underscore + * check to see if it's in this form + * _[a-z0-9] and if it's a character encoding + * If not, let the normal 'word parser' + * handle it. + */ +static size_t parse_underscore(sfilter *sf) +{ + char ch; + const char *cs = sf->s; + size_t slen = sf->slen; + size_t pos = sf->pos; + + size_t xlen = strlenspn(cs + pos + 1, slen - pos - 1, + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (xlen == 0) { + return parse_word(sf); + } + st_assign(sf->current, TYPE_BAREWORD, pos, xlen, cs + pos); + ch = sf->lookup(sf, LOOKUP_TYPE, sf->current->val, sf->current->len); + if (ch == TYPE_SQLTYPE) { + sf->current->type = TYPE_SQLTYPE; + return xlen + 1; + } + return parse_word(sf); +} + +static size_t parse_ustring(sfilter * sf) +{ + const char *cs = sf->s; + size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 2 < slen && cs[pos+1] == '&' && cs[pos+2] == '\'') { + sf->pos += 2; + pos = parse_string(sf); + sf->current->str_open = 'u'; + if (sf->current->str_close == '\'') { + sf->current->str_close = 'u'; + } + return pos; + } else { + return parse_word(sf); + } +} + +static size_t parse_qstring_core(sfilter * sf, int offset) +{ + char ch; + const char *strend; + const char *cs = sf->s; + size_t slen = sf->slen; + size_t pos = sf->pos + offset; + + /* if we are already at end of string.. + if current char is not q or Q + if we don't have 2 more chars + if char2 != a single quote + then, just treat as word + */ + if (pos >= slen || + (cs[pos] != 'q' && cs[pos] != 'Q') || + pos + 2 >= slen || + cs[pos + 1] != '\'') { + return parse_word(sf); + } + + ch = cs[pos + 2]; + if (ch < 33 && ch > 127) { + return parse_word(sf); + } + switch (ch) { + case '(' : ch = ')'; break; + case '[' : ch = ']'; break; + case '{' : ch = '}'; break; + case '<' : ch = '>'; break; + } + + strend = memchr2(cs + pos + 3, slen - pos - 3, ch, '\''); + if (strend == NULL) { + st_assign(sf->current, TYPE_STRING, pos + 3, slen - pos - 3, cs + pos + 3); + sf->current->str_open = 'q'; + sf->current->str_close = CHAR_NULL; + return slen; + } else { + st_assign(sf->current, TYPE_STRING, pos + 3, strend - cs - pos - 3, cs + pos + 3); + sf->current->str_open = 'q'; + sf->current->str_close = 'q'; + return (strend - cs) + 2; + } +} + +/* + * Oracle's q string + */ +static size_t parse_qstring(sfilter * sf) +{ + return parse_qstring_core(sf, 0); +} + +/* + * mysql's N'STRING' or + * ... Oracle's nq string + */ +static size_t parse_nqstring(sfilter * sf) +{ + size_t slen = sf->slen; + size_t pos = sf->pos; + if (pos + 2 < slen && sf->s[pos+1] == CHAR_SINGLE) { + return parse_estring(sf); + } + return parse_qstring_core(sf, 1); +} + +/* + * binary literal string + * re: [bB]'[01]*' + */ +static size_t parse_bstring(sfilter *sf) +{ + size_t wlen; + const char *cs = sf->s; + size_t pos = sf->pos; + size_t slen = sf->slen; + + /* need at least 2 more characters + * if next char isn't a single quote, then + * continue as normal word + */ + if (pos + 2 >= slen || cs[pos+1] != '\'') { + return parse_word(sf); + } + + wlen = strlenspn(cs + pos + 2, sf->slen - pos - 2, "01"); + if (pos + 2 + wlen >= slen || cs[pos + 2 + wlen] != '\'') { + return parse_word(sf); + } + st_assign(sf->current, TYPE_NUMBER, pos, wlen + 3, cs + pos); + return pos + 2 + wlen + 1; +} + +/* + * hex literal string + * re: [XX]'[0123456789abcdefABCDEF]*' + * mysql has requirement of having EVEN number of chars, + * but pgsql does not + */ +static size_t parse_xstring(sfilter *sf) +{ + size_t wlen; + const char *cs = sf->s; + size_t pos = sf->pos; + size_t slen = sf->slen; + + /* need at least 2 more characters + * if next char isn't a single quote, then + * continue as normal word + */ + if (pos + 2 >= slen || cs[pos+1] != '\'') { + return parse_word(sf); + } + + wlen = strlenspn(cs + pos + 2, sf->slen - pos - 2, "0123456789ABCDEFabcdef"); + if (pos + 2 + wlen >= slen || cs[pos + 2 + wlen] != '\'') { + return parse_word(sf); + } + st_assign(sf->current, TYPE_NUMBER, pos, wlen + 3, cs + pos); + return pos + 2 + wlen + 1; +} + +static size_t parse_word(sfilter * sf) +{ + char ch; + char delim; + size_t i; + const char *cs = sf->s; + size_t pos = sf->pos; + size_t wlen = strlencspn(cs + pos, sf->slen - pos, + " <>:\\?=@!#~+-*/&|^%(),';\t\n\v\f\r\"\000"); + + st_assign(sf->current, TYPE_BAREWORD, pos, wlen, cs + pos); + + /* now we need to look inside what we good for "." and "`" + * and see if what is before is a keyword or not + */ + for (i =0; i < sf->current->len; ++i) { + delim = sf->current->val[i]; + if (delim == '.' || delim == '`') { + ch = sf->lookup(sf, LOOKUP_WORD, sf->current->val, i); + if (ch != TYPE_NONE && ch != TYPE_BAREWORD) { + /* needed for swig */ + st_clear(sf->current); + /* + * we got something like "SELECT.1" + * or SELECT`column` + */ + st_assign(sf->current, ch, pos, i, cs + pos); + return pos + i; + } + } + } + + /* + * do normal lookup with word including '.' + */ + if (wlen < LIBINJECTION_SQLI_TOKEN_SIZE) { + + ch = sf->lookup(sf, LOOKUP_WORD, sf->current->val, wlen); + + if (ch == CHAR_NULL) { + ch = TYPE_BAREWORD; + } + sf->current->type = ch; + } + return pos + wlen; +} + +/* MySQL backticks are a cross between string and + * and a bare word. + * + */ +static size_t parse_tick(sfilter* sf) +{ + size_t pos = parse_string_core(sf->s, sf->slen, sf->pos, sf->current, '`', 1); + + /* 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 = sf->lookup(sf, LOOKUP_WORD, sf->current->val, sf->current->len); + if (ch == TYPE_FUNCTION) { + /* if it's a function, then convert token */ + sf->current->type = TYPE_FUNCTION; + } else { + /* otherwise it's a 'n' type -- mysql treats + * everything as a bare word + */ + sf->current->type = TYPE_STRING; + } + return pos; +} + +static size_t parse_var(sfilter * sf) +{ + size_t xlen; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos + 1; + + /* + * 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 (pos < slen && cs[pos] == '@') { + pos += 1; + sf->current->count = 2; + } else { + sf->current->count = 1; + } + + /* + * MySQL allows @@`version` + */ + if (pos < slen) { + if (cs[pos] == '`') { + sf->pos = pos; + pos = parse_tick(sf); + sf->current->type = TYPE_VARIABLE; + return pos; + } else if (cs[pos] == CHAR_SINGLE || cs[pos] == CHAR_DOUBLE) { + sf->pos = pos; + pos = parse_string(sf); + sf->current->type = TYPE_VARIABLE; + return pos; + } + } + + + xlen = strlencspn(cs + pos, slen - pos, + " <>:\\?=@!#~+-*/&|^%(),';\t\n\v\f\r'`\""); + if (xlen == 0) { + st_assign(sf->current, TYPE_VARIABLE, pos, 0, cs + pos); + return pos; + } else { + st_assign(sf->current, TYPE_VARIABLE, pos, xlen, cs + pos); + return pos + xlen; + } +} + +static size_t parse_money(sfilter *sf) +{ + size_t xlen; + const char* strend; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + if (pos + 1 == slen) { + /* end of line */ + st_assign_char(sf->current, TYPE_BAREWORD, pos, 1, '$'); + return slen; + } + + /* + * $1,000.00 or $1.000,00 ok! + * This also parses $....,,,111 but that's ok + */ + + xlen = strlenspn(cs + pos + 1, slen - pos - 1, "0123456789.,"); + if (xlen == 0) { + if (cs[pos + 1] == '$') { + /* we have $$ .. find ending $$ and make string */ + strend = memchr2(cs + pos + 2, slen - pos -2, '$', '$'); + if (strend == NULL) { + /* fell off edge */ + st_assign(sf->current, TYPE_STRING, pos + 2, slen - (pos + 2), cs + pos + 2); + sf->current->str_open = '$'; + sf->current->str_close = CHAR_NULL; + return slen; + } else { + st_assign(sf->current, TYPE_STRING, pos + 2, strend - (cs + pos + 2), cs + pos + 2); + sf->current->str_open = '$'; + sf->current->str_close = '$'; + return strend - cs + 2; + } + } else { + /* ok it's not a number or '$$', but maybe it's pgsql "$ quoted strings" */ + xlen = strlenspn(cs + pos + 1, slen - pos - 1, "abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (xlen == 0) { + /* hmm it's "$" _something_ .. just add $ and keep going*/ + st_assign_char(sf->current, TYPE_BAREWORD, pos, 1, '$'); + return pos + 1; + } + /* we have $foobar????? */ + /* is it $foobar$ */ + if (pos + xlen + 1 == slen || cs[pos+xlen+1] != '$') { + /* not $foobar$, or fell off edge */ + st_assign_char(sf->current, TYPE_BAREWORD, pos, 1, '$'); + return pos + 1; + } + + /* we have $foobar$ ... find it again */ + strend = my_memmem(cs+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2); + + if (strend == NULL) { + /* fell off edge */ + st_assign(sf->current, TYPE_STRING, pos+xlen+2, slen - pos - xlen - 2, cs+pos+xlen+2); + sf->current->str_open = '$'; + sf->current->str_close = CHAR_NULL; + return slen; + } else { + /* got one */ + st_assign(sf->current, TYPE_STRING, pos+xlen+2, strend - (cs + pos + xlen + 2), cs+pos+xlen+2); + sf->current->str_open = '$'; + sf->current->str_close = '$'; + return (strend + xlen + 2) - cs; + } + } + } else if (xlen == 1 && cs[pos + 1] == '.') { + /* $. should parsed as a word */ + return parse_word(sf); + } else { + st_assign(sf->current, TYPE_NUMBER, pos, 1 + xlen, cs + pos); + return pos + 1 + xlen; + } +} + +static size_t parse_number(sfilter * sf) +{ + size_t xlen; + size_t start; + const char* digits = NULL; + const char *cs = sf->s; + const size_t slen = sf->slen; + size_t pos = sf->pos; + + /* cs[pos] == '0' has 1/10 chance of being true, + * while pos+1< slen is almost always true + */ + if (cs[pos] == '0' && pos + 1 < slen) { + if (cs[pos + 1] == 'X' || cs[pos + 1] == 'x') { + digits = "0123456789ABCDEFabcdef"; + } else if (cs[pos + 1] == 'B' || cs[pos + 1] == 'b') { + digits = "01"; + } + + if (digits) { + xlen = strlenspn(cs + pos + 2, slen - pos - 2, digits); + if (xlen == 0) { + st_assign(sf->current, TYPE_BAREWORD, pos, 2, cs + pos); + return pos + 2; + } else { + st_assign(sf->current, TYPE_NUMBER, pos, 2 + xlen, cs + pos); + return pos + 2 + xlen; + } + } + } + + start = pos; + while (pos < slen && ISDIGIT(cs[pos])) { + pos += 1; + } + + if (pos < slen && cs[pos] == '.') { + pos += 1; + while (pos < slen && ISDIGIT(cs[pos])) { + pos += 1; + } + if (pos - start == 1) { + st_assign_char(sf->current, TYPE_BAREWORD, start, 1, '.'); + return pos; + } + } + + if (pos < slen) { + if (cs[pos] == 'E' || cs[pos] == 'e') { + pos += 1; + if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) { + pos += 1; + } + while (pos < slen && ISDIGIT(cs[pos])) { + pos += 1; + } + } + } + + /* oracle's ending float or double suffix + * http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements003.htm#i139891 + */ + if (pos < slen) { + if (cs[pos] == 'd' || cs[pos] == 'D' || cs[pos] == 'f' || cs[pos] == 'F') { + pos += 1; + } + } + + st_assign(sf->current, TYPE_NUMBER, start, pos - start, cs + start); + return pos; +} + +int libinjection_sqli_tokenize(sfilter * sf) +{ + pt2Function fnptr; + size_t *pos = &sf->pos; + stoken_t *current = sf->current; + const char *s = sf->s; + const size_t slen = sf->slen; + + if (slen == 0) { + return FALSE; + } + + st_clear(current); + sf->current = current; + + /* + * if we are at beginning of string + * and in single-quote or double quote mode + * then pretend the input starts with a quote + */ + if (*pos == 0 && (sf->flags & (FLAG_QUOTE_SINGLE | FLAG_QUOTE_DOUBLE))) { + *pos = parse_string_core(s, slen, 0, current, flag2delim(sf->flags), 0); + sf->stats_tokens += 1; + return TRUE; + } + + while (*pos < slen) { + + /* + * get current character + */ + const unsigned ch = (unsigned int) (s[*pos]); + + /* + * if not ascii, then continue... + * actually probably need to just assuming + * it's a string + */ + if (ch > 127) { + fnptr = parse_word; + } else { + + /* + * look up the parser, and call it + * + * Porting Note: this is mapping of char to function + * charparsers[ch]() + */ + fnptr = char_parse_map[ch]; + } + *pos = (*fnptr) (sf); + + /* + * + */ + if (current->type != CHAR_NULL) { + sf->stats_tokens += 1; + return TRUE; + } + } + return FALSE; +} + +void libinjection_sqli_init(sfilter * sf, const char *s, size_t len, int flags) +{ + if (flags == 0) { + flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; + } + + memset(sf, 0, sizeof(sfilter)); + sf->s = s; + sf->slen = len; + sf->lookup = libinjection_sqli_lookup_word; + sf->userdata = 0; + sf->flags = flags; + sf->current = &(sf->tokenvec[0]); +} + +void libinjection_sqli_reset(sfilter * sf, int flags) +{ + if (flags == 0) { + flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; + } + libinjection_sqli_init(sf, sf->s, sf->slen, flags); + sf->lookup = sf->lookup; + sf->userdata = sf->userdata; +} + +void libinjection_sqli_callback(sfilter * sf, ptr_lookup_fn fn, void* userdata) +{ + if (fn == NULL) { + sf->lookup = libinjection_sqli_lookup_word; + sf->userdata = (void*)(NULL); + } else { + sf->lookup = fn; + sf->userdata = userdata; + } +} + +/** See if two tokens can be merged since they are compound SQL phrases. + * + * This takes two tokens, and, if they are the right type, + * merges their values together. Then checks to see if the + * new value is special using the PHRASES mapping. + * + * Example: "UNION" + "ALL" ==> "UNION ALL" + * + * C Security Notes: this is safe to use C-strings (null-terminated) + * since the types involved by definition do not have embedded nulls + * (e.g. there is no keyword with embedded null) + * + * Porting Notes: since this is C, it's oddly complicated. + * This is just: multikeywords[token.value + ' ' + token2.value] + * + */ +static int syntax_merge_words(sfilter * sf,stoken_t * a, stoken_t * b) +{ + size_t sz1; + size_t sz2; + size_t sz3; + char tmp[LIBINJECTION_SQLI_TOKEN_SIZE]; + char ch; + + /* first token is of right type? */ + if (! + (a->type == TYPE_KEYWORD || a->type == TYPE_BAREWORD || a->type == TYPE_OPERATOR || + a->type == TYPE_UNION || a->type == TYPE_EXPRESSION || a->type == TYPE_SQLTYPE)) { + return CHAR_NULL; + } + + if (b->type != TYPE_KEYWORD && b->type != TYPE_BAREWORD && + b->type != TYPE_OPERATOR && b->type != TYPE_SQLTYPE && + b->type != TYPE_LOGIC_OPERATOR && + b->type != TYPE_UNION && b->type != TYPE_EXPRESSION) { + return CHAR_NULL; + } + + sz1 = a->len; + sz2 = b->len; + sz3 = sz1 + sz2 + 1; /* +1 for space in the middle */ + if (sz3 >= LIBINJECTION_SQLI_TOKEN_SIZE) { /* make sure there is room for ending null */ + return FALSE; + } + /* + * oddly annoying last.val + ' ' + current.val + */ + memcpy(tmp, a->val, sz1); + tmp[sz1] = ' '; + memcpy(tmp + sz1 + 1, b->val, sz2); + tmp[sz3] = CHAR_NULL; + + ch = sf->lookup(sf, LOOKUP_WORD, tmp, sz3); + + if (ch != CHAR_NULL) { + st_assign(a, ch, a->pos, sz3, tmp); + return TRUE; + } else { + return FALSE; + } +} + +int libinjection_sqli_fold(sfilter * sf) +{ + stoken_t last_comment; + + /* POS is the position of where the NEXT token goes */ + size_t pos = 0; + + /* LEFT is a count of how many tokens that are already + folded or processed (i.e. part of the fingerprint) */ + size_t left = 0; + + int more = 1; + + st_clear(&last_comment); + + /* Skip all initial comments, right-parens ( and unary operators + * + */ + sf->current = &(sf->tokenvec[0]); + while (more) { + more = libinjection_sqli_tokenize(sf); + if ( ! (sf->current->type == TYPE_COMMENT || sf->current->type == TYPE_LEFTPARENS || st_is_unary_op(sf->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 <= LIBINJECTION_SQLI_MAX_TOKENS && (pos - left) < 2) { + sf->current = &(sf->tokenvec[pos]); + more = libinjection_sqli_tokenize(sf); + if (more) { + if (sf->current->type == TYPE_COMMENT) { + st_copy(&last_comment, sf->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 == TYPE_STRING && sf->tokenvec[left+1].type == TYPE_STRING) { + pos -= 1; + sf->stats_folds += 1; + continue; + } else if (sf->tokenvec[left].type == TYPE_SEMICOLON && sf->tokenvec[left+1].type == TYPE_SEMICOLON) { + /* not sure how various engines handle + * 'select 1;;drop table foo' or + * 'select 1; /x foo x/; drop table foo' + * to prevent surprises, just fold away repeated semicolons + */ + pos -= 1; + sf->stats_folds += 1; + continue; + } else if (sf->tokenvec[left].type == TYPE_SEMICOLON && + sf->tokenvec[left+1].type == TYPE_FUNCTION && + cstrcasecmp("IF", sf->tokenvec[left+1].val, sf->tokenvec[left+1].len) == 0) { + /* IF is normally a function, except in Transact-SQL where it can be used as a + * standalone control flow operator, e.g. ; IF 1=1 ... + * if found after a semicolon, convert from 'f' type to 'T' type + */ + sf->tokenvec[left+1].type = TYPE_TSQL; + left += 2; + continue; /* reparse everything, but we probably can advance left, and pos */ + } else if ((sf->tokenvec[left].type ==TYPE_OPERATOR || sf->tokenvec[left].type ==TYPE_LOGIC_OPERATOR) && + st_is_unary_op(&sf->tokenvec[left+1])) { + pos -= 1; + sf->stats_folds += 1; + if (left > 0) { + left -= 1; + } + continue; + } else if (sf->tokenvec[left].type ==TYPE_LEFTPARENS && st_is_unary_op(&sf->tokenvec[left+1])) { + pos -= 1; + sf->stats_folds += 1; + if (left > 0) { + left -= 1; + } + continue; + } else if (syntax_merge_words(sf, &sf->tokenvec[left], &sf->tokenvec[left+1])) { + pos -= 1; + sf->stats_folds += 1; + if (left > 0) { + left -= 1; + } + continue; + } else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_VARIABLE) && + sf->tokenvec[left+1].type == TYPE_LEFTPARENS && ( + /* TSQL functions but common enough to be collumn names */ + cstrcasecmp("USER_ID", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("USER_NAME", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + + /* Function in MYSQL */ + cstrcasecmp("DATABASE", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("PASSWORD", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("USER", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + + /* Mysql words that act as a variable and are a function */ + + /* TSQL current_users is fake-variable */ + /* http://msdn.microsoft.com/en-us/library/ms176050.aspx */ + cstrcasecmp("CURRENT_USER", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("CURRENT_DATE", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("CURRENT_TIME", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("CURRENT_TIMESTAMP", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("LOCALTIME", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("LOCALTIMESTAMP", sf->tokenvec[left].val, sf->tokenvec[left].len) == 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 = TYPE_FUNCTION; + continue; + } else if (sf->tokenvec[left].type == TYPE_KEYWORD && ( + cstrcasecmp("IN", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || + cstrcasecmp("NOT IN", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 + )) { + + if (sf->tokenvec[left+1].type == TYPE_LEFTPARENS) { + /* got .... IN ( ... (or 'NOT IN') + * it's an operator + */ + sf->tokenvec[left].type = TYPE_OPERATOR; + } else { + /* + * it's a nothing + */ + sf->tokenvec[left].type = TYPE_BAREWORD; + } + + /* "IN" can be used as "IN BOOLEAN MODE" for mysql + * in which case merging of words can be done later + * other wise it acts as an equality operator __ IN (values..) + * + * here we got "IN" "(" so it's an operator. + * also back track to handle "NOT IN" + * might need to do the same with like + * two use cases "foo" LIKE "BAR" (normal operator) + * "foo" = LIKE(1,2) + */ + continue; + } else if (sf->tokenvec[left].type == TYPE_SQLTYPE && + (sf->tokenvec[left+1].type == TYPE_BAREWORD || sf->tokenvec[left+1].type == TYPE_NUMBER || + sf->tokenvec[left+1].type == TYPE_VARIABLE || sf->tokenvec[left+1].type == TYPE_STRING)) { + st_copy(&sf->tokenvec[left], &sf->tokenvec[left+1]); + pos -= 1; + sf->stats_folds += 1; + left = 0; + continue; + } else if (sf->tokenvec[left].type == TYPE_COLLATE && + sf->tokenvec[left+1].type == TYPE_BAREWORD) { + /* + * there are too many collation types.. so if the bareword has a "_" + * then it's TYPE_SQLTYPE + */ + if (strchr(sf->tokenvec[left+1].val, '_') != NULL) { + sf->tokenvec[left+1].type = TYPE_SQLTYPE; + } + } else if (sf->tokenvec[left].type == TYPE_BACKSLASH) { + if (st_is_arithmetic_op(&(sf->tokenvec[left+1]))) { + /* very weird case in TSQL where '\%1' is parsed as '0 % 1', etc */ + sf->tokenvec[left].type = TYPE_NUMBER; + } else { + /* just ignore it.. Again T-SQL seems to parse \1 as "1" */ + st_copy(&sf->tokenvec[left], &sf->tokenvec[left+1]); + pos -= 1; + sf->stats_folds += 1; + } + left = 0; + continue; + } + + /* all cases of handing 2 tokens is done + and nothing matched. Get one more token + */ + FOLD_DEBUG + while (more && pos <= LIBINJECTION_SQLI_MAX_TOKENS && pos - left < 3) { + sf->current = &(sf->tokenvec[pos]); + more = libinjection_sqli_tokenize(sf); + if (more) { + if (sf->current->type == TYPE_COMMENT) { + st_copy(&last_comment, sf->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 == TYPE_NUMBER && + sf->tokenvec[left+1].type == TYPE_OPERATOR && + sf->tokenvec[left+2].type == TYPE_NUMBER) { + pos -= 2; + continue; + } else if (sf->tokenvec[left].type == TYPE_OPERATOR && + sf->tokenvec[left+1].type != TYPE_LEFTPARENS && + sf->tokenvec[left+2].type == TYPE_OPERATOR) { + if (left > 0) { + left -= 1; + } + pos -= 2; + continue; + } else if (sf->tokenvec[left].type == TYPE_LOGIC_OPERATOR && + sf->tokenvec[left+2].type == TYPE_LOGIC_OPERATOR) { + pos -= 2; + continue; + } else if (sf->tokenvec[left].type == TYPE_VARIABLE && + sf->tokenvec[left+1].type == TYPE_OPERATOR && + (sf->tokenvec[left+2].type == TYPE_VARIABLE || sf->tokenvec[left+2].type == TYPE_NUMBER || + sf->tokenvec[left+2].type == TYPE_BAREWORD)) { + pos -= 2; + continue; + } else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_NUMBER ) && + sf->tokenvec[left+1].type == TYPE_OPERATOR && + (sf->tokenvec[left+2].type == TYPE_NUMBER || sf->tokenvec[left+2].type == TYPE_BAREWORD)) { + pos -= 2; + continue; + } else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_NUMBER || + sf->tokenvec[left].type == TYPE_VARIABLE || sf->tokenvec[left].type == TYPE_STRING) && + sf->tokenvec[left+1].type == TYPE_OPERATOR && streq(sf->tokenvec[left+1].val, "::") && + sf->tokenvec[left+2].type == TYPE_SQLTYPE) { + pos -= 2; + sf->stats_folds += 2; + continue; + } else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_NUMBER || sf->tokenvec[left].type == TYPE_STRING) && + sf->tokenvec[left+1].type == TYPE_COMMA && + (sf->tokenvec[left+2].type == TYPE_NUMBER || sf->tokenvec[left+2].type == TYPE_BAREWORD || sf->tokenvec[left+2].type == TYPE_STRING)) { + pos -= 2; + if (left > 0) { + left -= 1; + } + continue; + } else if ((sf->tokenvec[left].type == TYPE_EXPRESSION || + sf->tokenvec[left].type == TYPE_GROUP || + sf->tokenvec[left].type == TYPE_COMMA) && + st_is_unary_op(&sf->tokenvec[left+1]) && + sf->tokenvec[left+2].type == TYPE_LEFTPARENS) { + /* got something like SELECT + (, LIMIT + ( + * remove unary operator + */ + st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); + pos -= 1; + continue; + } else if ((sf->tokenvec[left].type == TYPE_KEYWORD || + sf->tokenvec[left].type == TYPE_EXPRESSION || + sf->tokenvec[left].type == TYPE_GROUP ) && + st_is_unary_op(&sf->tokenvec[left+1]) && + (sf->tokenvec[left+2].type == TYPE_NUMBER || + sf->tokenvec[left+2].type == TYPE_BAREWORD || + sf->tokenvec[left+2].type == TYPE_VARIABLE || + sf->tokenvec[left+2].type == TYPE_STRING || + sf->tokenvec[left+2].type == TYPE_FUNCTION )) { + // remove unary operators + // select - 1 + st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); + pos -= 1; + continue; + } else if (sf->tokenvec[left].type == TYPE_COMMA && + st_is_unary_op(&sf->tokenvec[left+1]) && + (sf->tokenvec[left+2].type == TYPE_NUMBER || + sf->tokenvec[left+2].type == TYPE_BAREWORD || + sf->tokenvec[left+2].type == TYPE_VARIABLE || + sf->tokenvec[left+2].type == TYPE_STRING || + sf->tokenvec[left+2].type == TYPE_FUNCTION )) { + /* + * interesting case turn ", -1" ->> ",1" PLUS we need to back up + * one token if possible to see if more folding can be done + * "1,-1" --> "1" + */ + st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); + if (left > 0) { + left -= 1; + } + /* pos is >= 3 so this is safe */ + assert(pos >= 3); + pos -= 3; + continue; + } else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_STRING)&& + (sf->tokenvec[left+1].type == TYPE_BAREWORD && sf->tokenvec[left+1].val[0] == '.') && + (sf->tokenvec[left+2].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_STRING)) { + /* 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 < LIBINJECTION_SQLI_MAX_TOKENS && last_comment.type == TYPE_COMMENT) { + 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 > LIBINJECTION_SQLI_MAX_TOKENS) { + left = LIBINJECTION_SQLI_MAX_TOKENS; + } + + return (int)left; +} + +/* secondary api: detects SQLi in a string, GIVEN a context. + * + * A context can be: + * * CHAR_NULL (\0), process as is + * * CHAR_SINGLE ('), process pretending input started with a + * single quote. + * * CHAR_DOUBLE ("), process pretending input started with a + * double quote. + * + */ +const char* libinjection_sqli_fingerprint(sfilter * sql_state, int flags) +{ + int i; + int tlen = 0; + + libinjection_sqli_reset(sql_state, flags); + + tlen = libinjection_sqli_fold(sql_state); + for (i = 0; i < tlen; ++i) { + sql_state->fingerprint[i] = sql_state->tokenvec[i].type; + } + + /* + * make the fingerprint pattern a c-string (null delimited) + */ + sql_state->fingerprint[tlen] = CHAR_NULL; + + /* + * check for 'X' in pattern, and then + * clear out all tokens + * + * this means parsing could not be done + * accurately due to pgsql's double comments + * or other syntax that isn't consistent. + * Should be very rare false positive + */ + if (strchr(sql_state->fingerprint, TYPE_EVIL)) { + /* needed for SWIG */ + memset((void*)sql_state->fingerprint, 0, LIBINJECTION_SQLI_MAX_TOKENS + 1); + memset((void*)sql_state->tokenvec[0].val, 0, LIBINJECTION_SQLI_TOKEN_SIZE); + + sql_state->fingerprint[0] = TYPE_EVIL; + + sql_state->tokenvec[0].type = TYPE_EVIL; + sql_state->tokenvec[0].val[0] = TYPE_EVIL; + sql_state->tokenvec[1].type = CHAR_NULL; + } + + return sql_state->fingerprint; +} + + +/** + * + */ +#define UNUSED(x) (void)(x) + +int libinjection_sqli_check_fingerprint(sfilter* sql_state) +{ + return libinjection_sqli_blacklist(sql_state) && + libinjection_sqli_not_whitelist(sql_state); +} + +char libinjection_sqli_lookup_word(sfilter *sql_state, int lookup_type, + const char* str, size_t len) +{ + if (lookup_type == LOOKUP_FINGERPRINT) { + return libinjection_sqli_check_fingerprint(sql_state) ? 'X' : '\0'; + } else { + return bsearch_keyword_type(str, len, sql_keywords, sql_keywords_sz); + } +} + +int libinjection_sqli_blacklist(sfilter* sql_state) +{ + char fp2[LIBINJECTION_SQLI_MAX_TOKENS + 2]; + char ch; + size_t i; + int patmatch = 0; + size_t len = strlen(sql_state->fingerprint); + + if (len < 1) { + sql_state->reason = __LINE__; + return FALSE; + } + + /* + to keep everything compatible, convert the + v0 fingerprint pattern to v1 + v0: up to 5 chars, mixed case + v1: 1 char is '0', up to 5 more chars, upper case + */ + + fp2[0] = '0'; + for (i = 0; i < len; ++i) { + ch = sql_state->fingerprint[i]; + if (ch >= 'a' && ch <= 'z') { + ch -= 0x20; + } + fp2[i+1] = ch; + } + fp2[i+1] = '\0'; + + patmatch = is_keyword(fp2, len + 1) == TYPE_FINGERPRINT; + + /* + * No match. + * + * Set sql_state->reason to current line number + * only for debugging purposes. + */ + if (!patmatch) { + sql_state->reason = __LINE__; + return FALSE; + } + + return TRUE; +} + +/* + * return TRUE if sqli, false is benign + */ +int libinjection_sqli_not_whitelist(sfilter* sql_state) +{ + /* + * We assume we got a SQLi match + * This next part just helps reduce false positives. + * + */ + char ch; + size_t tlen = strlen(sql_state->fingerprint); + + switch (tlen) { + case 2:{ + /* + * case 2 are "very small SQLi" which make them + * hard to tell from normal input... + */ + + if (sql_state->fingerprint[1] == TYPE_UNION) { + if (sql_state->stats_tokens == 2) { + /* not sure why but 1U comes up in Sqli attack + * likely part of parameter splitting/etc. + * lots of reasons why "1 union" might be normal + * input, so beep only if other SQLi things are present + */ + /* it really is a number and 'union' + * other wise it has folding or comments + */ + sql_state->reason = __LINE__; + return FALSE; + } else { + sql_state->reason = __LINE__; + return TRUE; + } + } + /* + * if 'comment' is '#' ignore.. too many FP + */ + if (sql_state->tokenvec[1].val[0] == '#') { + sql_state->reason = __LINE__; + return FALSE; + } + + /* + * if ending comment is contains 'sp_password' then it's sqli! + * MS Audit log appearantly ignores anything with + * 'sp_password' in it. Unable to find primary refernece to + * this "feature" of SQL Server but seems to be known sqli + * technique + */ + if (sql_state->tokenvec[1].type == TYPE_COMMENT && + my_memmem(sql_state->tokenvec[1].val, sql_state->tokenvec[1].len, + "sp_password", strlen("sp_password"))) { + sql_state->reason = __LINE__; + return TRUE; + } + + /* + * for fingerprint like 'nc', only comments of /x are treated + * as SQL... ending comments of "--" and "#" are not sqli + */ + if (sql_state->tokenvec[0].type == TYPE_BAREWORD && + sql_state->tokenvec[1].type == TYPE_COMMENT && + sql_state->tokenvec[1].val[0] != '/') { + sql_state->reason = __LINE__; + return FALSE; + } + + /* + * if '1c' ends with '/x' then it's sqli + */ + if (sql_state->tokenvec[0].type == TYPE_NUMBER && + sql_state->tokenvec[1].type == TYPE_COMMENT && + sql_state->tokenvec[1].val[0] == '/') { + return TRUE; + } + + /* + * if 'oc' then input must be 'CASE/x' + * used in HPP attack + */ + if (sql_state->tokenvec[0].type == TYPE_OPERATOR && + sql_state->tokenvec[1].type == TYPE_COMMENT && + sql_state->tokenvec[1].val[0] == '/' && + cstrcasecmp("CASE", sql_state->tokenvec[0].val, sql_state->tokenvec[0].len) != 0) + { + sql_state->reason = __LINE__; + return FALSE; + } + + /** + * there are some odd base64-looking query string values + * 1234-ABCDEFEhfhihwuefi-- + * which evaluate to "1c"... these are not SQLi + * but 1234-- probably is. + * Make sure the "1" in "1c" is actually a true decimal number + * + * Need to check -original- string since the folding step + * may have merged tokens, e.g. "1+FOO" is folded into "1" + * + * Note: evasion: 1*1-- + */ + if (sql_state->tokenvec[0].type == TYPE_NUMBER && + sql_state->tokenvec[1].type == TYPE_COMMENT) { + if (sql_state->stats_tokens > 2) { + /* we have some folding going on, highly likely sqli */ + sql_state->reason = __LINE__; + return TRUE; + } + /* + * we check that next character after the number is either whitespace, + * or '/' or a '-' ==> sqli. + */ + ch = sql_state->s[sql_state->tokenvec[0].len]; + if ( ch <= 32 ) { + /* next char was whitespace,e.g. "1234 --" + * this isn't exactly correct.. ideally we should skip over all whitespace + * but this seems to be ok for now + */ + return TRUE; + } + if (ch == '/' && sql_state->s[sql_state->tokenvec[0].len + 1] == '*') { + return TRUE; + } + if (ch == '-' && sql_state->s[sql_state->tokenvec[0].len + 1] == '-') { + return TRUE; + } + + sql_state->reason = __LINE__; + return FALSE; + } + + /* + * detect obvious sqli scans.. many people put '--' in plain text + * so only detect if input ends with '--', e.g. 1-- but not 1-- foo + */ + if ((sql_state->tokenvec[1].len > 2) + && sql_state->tokenvec[1].val[0] == '-') { + sql_state->reason = __LINE__; + return FALSE; + } + + break; + } /* case 2 */ + case 3:{ + /* + * ...foo' + 'bar... + * no opening quote, no closing quote + * and each string has data + */ + + if (streq(sql_state->fingerprint, "sos") + || streq(sql_state->fingerprint, "s&s")) { + + if ((sql_state->tokenvec[0].str_open == 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.... + */ + sql_state->reason = __LINE__; + return TRUE; + } + if (sql_state->stats_tokens == 3) { + sql_state->reason = __LINE__; + return FALSE; + } + + /* + * not sqli + */ + sql_state->reason = __LINE__; + return FALSE; + } else if (streq(sql_state->fingerprint, "s&n") || streq(sql_state->fingerprint, "n&1") || streq(sql_state->fingerprint, "1&1") || + streq(sql_state->fingerprint, "1&v") || streq(sql_state->fingerprint, "1&s")) { + /* 'sexy and 17' not sqli + * 'sexy and 17<18' sqli + */ + if (sql_state->stats_tokens == 3) { + sql_state->reason = __LINE__; + return FALSE; + } + } else if (streq(sql_state->fingerprint, "so1")) { + if (sql_state->tokenvec[0].str_open != CHAR_NULL) { + /* "foo" -1 is ok, foo"-1 is not */ + sql_state->reason = __LINE__; + return FALSE; + } + } else if (sql_state->tokenvec[1].type == TYPE_KEYWORD) { + if ((sql_state->tokenvec[1].len < 5) || + cstrcasecmp("INTO", sql_state->tokenvec[1].val, 4)) { + /* if it's not "INTO OUTFILE", or "INTO DUMPFILE" (MySQL) + * then treat as safe + */ + sql_state->reason = __LINE__; + return FALSE; + } + } + break; + } /* case 3 */ + case 4: + if (streq(sql_state->fingerprint, "s&1s")) { + /* look for ...foo" and 1=1 ` + * where the ending string is actually a comment in + * php mysql magic land. This check is needed + * since normal non sqli text often folds to + * s&1s.. this check figures that out + */ + if (sql_state->stats_tokens == 4) { + sql_state->reason = __LINE__; + return FALSE; + } + } + case 5: { + /* nothing right now */ + break; + } /* case 5 */ + } /* end switch */ + + return TRUE; +} + +/** Main API, detects SQLi in an input. + * + * + */ +static int reparse_as_mysql(sfilter * sql_state) +{ + return sql_state->stats_comment_ddx || + sql_state->stats_comment_hash; +} + +int libinjection_is_sqli(sfilter * sql_state) +{ + const char *s = sql_state->s; + size_t slen = sql_state->slen; + + /* + * no input? not sqli + */ + if (slen == 0) { + return FALSE; + } + + /* + * test input "as-is" + */ + libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); + if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT, + sql_state->fingerprint, strlen(sql_state->fingerprint))) { + return TRUE; + } else if (reparse_as_mysql(sql_state)) { + libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL); + if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT, + sql_state->fingerprint, strlen(sql_state->fingerprint))) { + return TRUE; + } + } + + /* + * if input has a single_quote, then + * test as if input was actually ' + * example: if input if "1' = 1", then pretend it's + * "'1' = 1" + * Porting Notes: example the same as doing + * is_string_sqli(sql_state, "'" + s, slen+1, NULL, fn, arg) + * + */ + if (memchr(s, CHAR_SINGLE, slen)) { + libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI); + if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT, + sql_state->fingerprint, strlen(sql_state->fingerprint))) { + return TRUE; + } else if (reparse_as_mysql(sql_state)) { + libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL); + if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT, + sql_state->fingerprint, strlen(sql_state->fingerprint))) { + return TRUE; + } + } + } + + /* + * same as above but with a double-quote " + */ + if (memchr(s, CHAR_DOUBLE, slen)) { + libinjection_sqli_fingerprint(sql_state, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL); + if (sql_state->lookup(sql_state, LOOKUP_FINGERPRINT, + sql_state->fingerprint, strlen(sql_state->fingerprint))) { + return TRUE; + } + } + + /* + * Hurray, input is not SQLi + */ + return FALSE; +} diff --git a/apache2/libinjection/libinjection_sqli.obj b/apache2/libinjection/libinjection_sqli.obj new file mode 100644 index 00000000..7b8a8649 Binary files /dev/null and b/apache2/libinjection/libinjection_sqli.obj differ diff --git a/apache2/libinjection/libinjection_sqli_data.h b/apache2/libinjection/libinjection_sqli_data.h new file mode 100644 index 00000000..49e910cc --- /dev/null +++ b/apache2/libinjection/libinjection_sqli_data.h @@ -0,0 +1,10228 @@ + +#ifndef _LIBINJECTION_SQLI_DATA_H +#define _LIBINJECTION_SQLI_DATA_H + +#include "libinjection.h" + +typedef struct { + const char *word; + char type; +} keyword_t; + +static size_t parse_money(sfilter * sf); +static size_t parse_other(sfilter * sf); +static size_t parse_white(sfilter * sf); +static size_t parse_operator1(sfilter *sf); +static size_t parse_char(sfilter *sf); +static size_t parse_hash(sfilter *sf); +static size_t parse_dash(sfilter *sf); +static size_t parse_slash(sfilter *sf); +static size_t parse_backslash(sfilter * sf); +static size_t parse_operator2(sfilter *sf); +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 size_t parse_underscore(sfilter * sf); +static size_t parse_ustring(sfilter * sf); +static size_t parse_qstring(sfilter * sf); +static size_t parse_nqstring(sfilter * sf); +static size_t parse_xstring(sfilter * sf); +static size_t parse_bstring(sfilter * sf); +static size_t parse_estring(sfilter * sf); + + +typedef size_t (*pt2Function)(sfilter *sf); +static const pt2Function char_parse_map[] = { + &parse_white, /* 0 */ + &parse_white, /* 1 */ + &parse_white, /* 2 */ + &parse_white, /* 3 */ + &parse_white, /* 4 */ + &parse_white, /* 5 */ + &parse_white, /* 6 */ + &parse_white, /* 7 */ + &parse_white, /* 8 */ + &parse_white, /* 9 */ + &parse_white, /* 10 */ + &parse_white, /* 11 */ + &parse_white, /* 12 */ + &parse_white, /* 13 */ + &parse_white, /* 14 */ + &parse_white, /* 15 */ + &parse_white, /* 16 */ + &parse_white, /* 17 */ + &parse_white, /* 18 */ + &parse_white, /* 19 */ + &parse_white, /* 20 */ + &parse_white, /* 21 */ + &parse_white, /* 22 */ + &parse_white, /* 23 */ + &parse_white, /* 24 */ + &parse_white, /* 25 */ + &parse_white, /* 26 */ + &parse_white, /* 27 */ + &parse_white, /* 28 */ + &parse_white, /* 29 */ + &parse_white, /* 30 */ + &parse_white, /* 31 */ + &parse_white, /* 32 */ + &parse_operator2, /* 33 */ + &parse_string, /* 34 */ + &parse_hash, /* 35 */ + &parse_money, /* 36 */ + &parse_operator1, /* 37 */ + &parse_operator2, /* 38 */ + &parse_string, /* 39 */ + &parse_char, /* 40 */ + &parse_char, /* 41 */ + &parse_operator2, /* 42 */ + &parse_operator1, /* 43 */ + &parse_char, /* 44 */ + &parse_dash, /* 45 */ + &parse_number, /* 46 */ + &parse_slash, /* 47 */ + &parse_number, /* 48 */ + &parse_number, /* 49 */ + &parse_number, /* 50 */ + &parse_number, /* 51 */ + &parse_number, /* 52 */ + &parse_number, /* 53 */ + &parse_number, /* 54 */ + &parse_number, /* 55 */ + &parse_number, /* 56 */ + &parse_number, /* 57 */ + &parse_operator2, /* 58 */ + &parse_char, /* 59 */ + &parse_operator2, /* 60 */ + &parse_operator2, /* 61 */ + &parse_operator2, /* 62 */ + &parse_other, /* 63 */ + &parse_var, /* 64 */ + &parse_word, /* 65 */ + &parse_bstring, /* 66 */ + &parse_word, /* 67 */ + &parse_word, /* 68 */ + &parse_estring, /* 69 */ + &parse_word, /* 70 */ + &parse_word, /* 71 */ + &parse_word, /* 72 */ + &parse_word, /* 73 */ + &parse_word, /* 74 */ + &parse_word, /* 75 */ + &parse_word, /* 76 */ + &parse_word, /* 77 */ + &parse_nqstring, /* 78 */ + &parse_word, /* 79 */ + &parse_word, /* 80 */ + &parse_qstring, /* 81 */ + &parse_word, /* 82 */ + &parse_word, /* 83 */ + &parse_word, /* 84 */ + &parse_ustring, /* 85 */ + &parse_word, /* 86 */ + &parse_word, /* 87 */ + &parse_xstring, /* 88 */ + &parse_word, /* 89 */ + &parse_word, /* 90 */ + &parse_other, /* 91 */ + &parse_backslash, /* 92 */ + &parse_other, /* 93 */ + &parse_operator1, /* 94 */ + &parse_underscore, /* 95 */ + &parse_tick, /* 96 */ + &parse_word, /* 97 */ + &parse_bstring, /* 98 */ + &parse_word, /* 99 */ + &parse_word, /* 100 */ + &parse_estring, /* 101 */ + &parse_word, /* 102 */ + &parse_word, /* 103 */ + &parse_word, /* 104 */ + &parse_word, /* 105 */ + &parse_word, /* 106 */ + &parse_word, /* 107 */ + &parse_word, /* 108 */ + &parse_word, /* 109 */ + &parse_nqstring, /* 110 */ + &parse_word, /* 111 */ + &parse_word, /* 112 */ + &parse_qstring, /* 113 */ + &parse_word, /* 114 */ + &parse_word, /* 115 */ + &parse_word, /* 116 */ + &parse_ustring, /* 117 */ + &parse_word, /* 118 */ + &parse_word, /* 119 */ + &parse_xstring, /* 120 */ + &parse_word, /* 121 */ + &parse_word, /* 122 */ + &parse_other, /* 123 */ + &parse_operator2, /* 124 */ + &parse_other, /* 125 */ + &parse_operator1, /* 126 */ + &parse_white, /* 127 */ +}; + +static const keyword_t sql_keywords[] = { + {"!!", 'o'}, + {"!<", 'o'}, + {"!=", 'o'}, + {"!>", 'o'}, + {"%=", 'o'}, + {"&&", '&'}, + {"&=", 'o'}, + {"*=", 'o'}, + {"+=", 'o'}, + {"-=", 'o'}, + {"/=", 'o'}, + {"0&((((", 'F'}, + {"0&(((1", 'F'}, + {"0&(((F", 'F'}, + {"0&(((N", 'F'}, + {"0&(((S", 'F'}, + {"0&(((V", 'F'}, + {"0&((1)", 'F'}, + {"0&((1O", 'F'}, + {"0&((F(", 'F'}, + {"0&((N)", 'F'}, + {"0&((NO", 'F'}, + {"0&((S)", 'F'}, + {"0&((SO", 'F'}, + {"0&((V)", 'F'}, + {"0&((VO", 'F'}, + {"0&(1))", 'F'}, + {"0&(1)O", 'F'}, + {"0&(1)U", 'F'}, + {"0&(1O(", 'F'}, + {"0&(1OF", 'F'}, + {"0&(1OS", 'F'}, + {"0&(1OV", 'F'}, + {"0&(F((", 'F'}, + {"0&(F()", 'F'}, + {"0&(F(1", 'F'}, + {"0&(F(F", 'F'}, + {"0&(F(N", 'F'}, + {"0&(F(S", 'F'}, + {"0&(F(V", 'F'}, + {"0&(N))", 'F'}, + {"0&(N)O", 'F'}, + {"0&(N)U", 'F'}, + {"0&(NO(", 'F'}, + {"0&(NOF", 'F'}, + {"0&(NOS", 'F'}, + {"0&(NOV", 'F'}, + {"0&(S))", 'F'}, + {"0&(S)O", 'F'}, + {"0&(S)U", 'F'}, + {"0&(SO(", 'F'}, + {"0&(SO1", 'F'}, + {"0&(SOF", 'F'}, + {"0&(SON", 'F'}, + {"0&(SOS", 'F'}, + {"0&(SOV", 'F'}, + {"0&(V))", 'F'}, + {"0&(V)O", 'F'}, + {"0&(V)U", 'F'}, + {"0&(VO(", 'F'}, + {"0&(VOF", 'F'}, + {"0&(VOS", 'F'}, + {"0&1O((", 'F'}, + {"0&1O(1", 'F'}, + {"0&1O(F", 'F'}, + {"0&1O(N", 'F'}, + {"0&1O(S", 'F'}, + {"0&1O(V", 'F'}, + {"0&1OF(", 'F'}, + {"0&1OS(", 'F'}, + {"0&1OS1", 'F'}, + {"0&1OSF", 'F'}, + {"0&1OSO", 'F'}, + {"0&1OSU", 'F'}, + {"0&1OSV", 'F'}, + {"0&1OV(", 'F'}, + {"0&1OVF", 'F'}, + {"0&1OVO", 'F'}, + {"0&1OVS", 'F'}, + {"0&1OVU", 'F'}, + {"0&1UE(", 'F'}, + {"0&1UE1", 'F'}, + {"0&1UEF", 'F'}, + {"0&1UEK", 'F'}, + {"0&1UEN", 'F'}, + {"0&1UES", 'F'}, + {"0&1UEV", 'F'}, + {"0&F(((", 'F'}, + {"0&F(()", 'F'}, + {"0&F((1", 'F'}, + {"0&F((F", 'F'}, + {"0&F((N", 'F'}, + {"0&F((S", 'F'}, + {"0&F((V", 'F'}, + {"0&F())", 'F'}, + {"0&F()O", 'F'}, + {"0&F()U", 'F'}, + {"0&F(1)", 'F'}, + {"0&F(1O", 'F'}, + {"0&F(F(", 'F'}, + {"0&F(N)", 'F'}, + {"0&F(NO", 'F'}, + {"0&F(S)", 'F'}, + {"0&F(SO", 'F'}, + {"0&F(V)", 'F'}, + {"0&F(VO", 'F'}, + {"0&NO((", 'F'}, + {"0&NO(1", 'F'}, + {"0&NO(F", 'F'}, + {"0&NO(N", 'F'}, + {"0&NO(S", 'F'}, + {"0&NO(V", 'F'}, + {"0&NOF(", 'F'}, + {"0&NOS(", 'F'}, + {"0&NOS1", 'F'}, + {"0&NOSF", 'F'}, + {"0&NOSO", 'F'}, + {"0&NOSU", 'F'}, + {"0&NOSV", 'F'}, + {"0&NOV(", 'F'}, + {"0&NOVF", 'F'}, + {"0&NOVO", 'F'}, + {"0&NOVS", 'F'}, + {"0&NOVU", 'F'}, + {"0&NUE(", 'F'}, + {"0&NUE1", 'F'}, + {"0&NUEF", 'F'}, + {"0&NUEK", 'F'}, + {"0&NUEN", 'F'}, + {"0&NUES", 'F'}, + {"0&NUEV", 'F'}, + {"0&SO((", 'F'}, + {"0&SO(1", 'F'}, + {"0&SO(F", 'F'}, + {"0&SO(N", 'F'}, + {"0&SO(S", 'F'}, + {"0&SO(V", 'F'}, + {"0&SO1(", 'F'}, + {"0&SO1F", 'F'}, + {"0&SO1N", 'F'}, + {"0&SO1O", 'F'}, + {"0&SO1S", 'F'}, + {"0&SO1U", 'F'}, + {"0&SO1V", 'F'}, + {"0&SOF(", 'F'}, + {"0&SON(", 'F'}, + {"0&SON1", 'F'}, + {"0&SONF", 'F'}, + {"0&SONO", 'F'}, + {"0&SONU", 'F'}, + {"0&SOS(", 'F'}, + {"0&SOS1", 'F'}, + {"0&SOSF", 'F'}, + {"0&SOSO", 'F'}, + {"0&SOSU", 'F'}, + {"0&SOSV", 'F'}, + {"0&SOV(", 'F'}, + {"0&SOVF", 'F'}, + {"0&SOVO", 'F'}, + {"0&SOVS", 'F'}, + {"0&SOVU", 'F'}, + {"0&SUE(", 'F'}, + {"0&SUE1", 'F'}, + {"0&SUEF", 'F'}, + {"0&SUEK", 'F'}, + {"0&SUEN", 'F'}, + {"0&SUES", 'F'}, + {"0&SUEV", 'F'}, + {"0&VO((", 'F'}, + {"0&VO(1", 'F'}, + {"0&VO(F", 'F'}, + {"0&VO(N", 'F'}, + {"0&VO(S", 'F'}, + {"0&VO(V", 'F'}, + {"0&VOF(", 'F'}, + {"0&VOS(", 'F'}, + {"0&VOS1", 'F'}, + {"0&VOSF", 'F'}, + {"0&VOSO", 'F'}, + {"0&VOSU", 'F'}, + {"0&VOSV", 'F'}, + {"0&VUE(", 'F'}, + {"0&VUE1", 'F'}, + {"0&VUEF", 'F'}, + {"0&VUEK", 'F'}, + {"0&VUEN", 'F'}, + {"0&VUES", 'F'}, + {"0&VUEV", 'F'}, + {"0)))))", 'F'}, + {"0))))U", 'F'}, + {"0)))UE", 'F'}, + {"0))UE(", 'F'}, + {"0))UE1", 'F'}, + {"0))UEF", 'F'}, + {"0))UEK", 'F'}, + {"0))UEN", 'F'}, + {"0))UES", 'F'}, + {"0))UEV", 'F'}, + {"0)UE((", 'F'}, + {"0)UE(1", 'F'}, + {"0)UE(F", 'F'}, + {"0)UE(N", 'F'}, + {"0)UE(S", 'F'}, + {"0)UE(V", 'F'}, + {"0)UE1K", 'F'}, + {"0)UE1O", 'F'}, + {"0)UEF(", 'F'}, + {"0)UEK(", 'F'}, + {"0)UEK1", 'F'}, + {"0)UEKF", 'F'}, + {"0)UEKN", 'F'}, + {"0)UEKS", 'F'}, + {"0)UEKV", 'F'}, + {"0)UENK", 'F'}, + {"0)UENO", 'F'}, + {"0)UESK", 'F'}, + {"0)UESO", 'F'}, + {"0)UEVK", 'F'}, + {"0)UEVO", 'F'}, + {"01&(((", 'F'}, + {"01&((1", 'F'}, + {"01&((E", 'F'}, + {"01&((F", 'F'}, + {"01&((N", 'F'}, + {"01&((S", 'F'}, + {"01&((V", 'F'}, + {"01&(1&", 'F'}, + {"01&(1)", 'F'}, + {"01&(1,", 'F'}, + {"01&(1O", 'F'}, + {"01&(E(", 'F'}, + {"01&(E1", 'F'}, + {"01&(EF", 'F'}, + {"01&(EK", 'F'}, + {"01&(EN", 'F'}, + {"01&(EO", 'F'}, + {"01&(ES", 'F'}, + {"01&(EV", 'F'}, + {"01&(F(", 'F'}, + {"01&(N&", 'F'}, + {"01&(N)", 'F'}, + {"01&(N,", 'F'}, + {"01&(NO", 'F'}, + {"01&(S&", 'F'}, + {"01&(S)", 'F'}, + {"01&(S,", 'F'}, + {"01&(SO", 'F'}, + {"01&(V&", 'F'}, + {"01&(V)", 'F'}, + {"01&(V,", 'F'}, + {"01&(VO", 'F'}, + {"01&1", 'F'}, + {"01&1&(", 'F'}, + {"01&1&1", 'F'}, + {"01&1&F", 'F'}, + {"01&1&N", 'F'}, + {"01&1&S", 'F'}, + {"01&1&V", 'F'}, + {"01&1)&", 'F'}, + {"01&1))", 'F'}, + {"01&1)U", 'F'}, + {"01&1;", 'F'}, + {"01&1;C", 'F'}, + {"01&1;E", 'F'}, + {"01&1;T", 'F'}, + {"01&1B(", 'F'}, + {"01&1B1", 'F'}, + {"01&1BF", 'F'}, + {"01&1BN", 'F'}, + {"01&1BS", 'F'}, + {"01&1BV", 'F'}, + {"01&1C", 'F'}, + {"01&1EK", 'F'}, + {"01&1EN", 'F'}, + {"01&1F(", 'F'}, + {"01&1K(", 'F'}, + {"01&1K1", 'F'}, + {"01&1KF", 'F'}, + {"01&1KN", 'F'}, + {"01&1KS", 'F'}, + {"01&1KV", 'F'}, + {"01&1O(", 'F'}, + {"01&1OF", 'F'}, + {"01&1OO", 'F'}, + {"01&1OS", 'F'}, + {"01&1OV", 'F'}, + {"01&1TN", 'F'}, + {"01&1U", 'F'}, + {"01&1U(", 'F'}, + {"01&1U;", 'F'}, + {"01&1UC", 'F'}, + {"01&1UE", 'F'}, + {"01&E((", 'F'}, + {"01&E(1", 'F'}, + {"01&E(F", 'F'}, + {"01&E(N", 'F'}, + {"01&E(O", 'F'}, + {"01&E(S", 'F'}, + {"01&E(V", 'F'}, + {"01&E1", 'F'}, + {"01&E1;", 'F'}, + {"01&E1C", 'F'}, + {"01&E1K", 'F'}, + {"01&E1O", 'F'}, + {"01&EF(", 'F'}, + {"01&EK(", 'F'}, + {"01&EK1", 'F'}, + {"01&EKF", 'F'}, + {"01&EKN", 'F'}, + {"01&EKS", 'F'}, + {"01&EKU", 'F'}, + {"01&EKV", 'F'}, + {"01&EN", 'F'}, + {"01&EN;", 'F'}, + {"01&ENC", 'F'}, + {"01&ENK", 'F'}, + {"01&ENO", 'F'}, + {"01&ES", 'F'}, + {"01&ES;", 'F'}, + {"01&ESC", 'F'}, + {"01&ESK", 'F'}, + {"01&ESO", 'F'}, + {"01&EUE", 'F'}, + {"01&EV", 'F'}, + {"01&EV;", 'F'}, + {"01&EVC", 'F'}, + {"01&EVK", 'F'}, + {"01&EVO", 'F'}, + {"01&F((", 'F'}, + {"01&F()", 'F'}, + {"01&F(1", 'F'}, + {"01&F(F", 'F'}, + {"01&F(N", 'F'}, + {"01&F(S", 'F'}, + {"01&F(V", 'F'}, + {"01&K&(", 'F'}, + {"01&K&1", 'F'}, + {"01&K&F", 'F'}, + {"01&K&N", 'F'}, + {"01&K&S", 'F'}, + {"01&K&V", 'F'}, + {"01&K((", 'F'}, + {"01&K(1", 'F'}, + {"01&K(F", 'F'}, + {"01&K(N", 'F'}, + {"01&K(S", 'F'}, + {"01&K(V", 'F'}, + {"01&K1O", 'F'}, + {"01&KF(", 'F'}, + {"01&KNK", 'F'}, + {"01&KO(", 'F'}, + {"01&KO1", 'F'}, + {"01&KOF", 'F'}, + {"01&KOK", 'F'}, + {"01&KON", 'F'}, + {"01&KOS", 'F'}, + {"01&KOV", 'F'}, + {"01&KSO", 'F'}, + {"01&KVO", 'F'}, + {"01&N&(", 'F'}, + {"01&N&1", 'F'}, + {"01&N&F", 'F'}, + {"01&N&N", 'F'}, + {"01&N&S", 'F'}, + {"01&N&V", 'F'}, + {"01&N)&", 'F'}, + {"01&N))", 'F'}, + {"01&N)U", 'F'}, + {"01&N;", 'F'}, + {"01&N;C", 'F'}, + {"01&N;E", 'F'}, + {"01&N;T", 'F'}, + {"01&NB(", 'F'}, + {"01&NB1", 'F'}, + {"01&NBF", 'F'}, + {"01&NBN", 'F'}, + {"01&NBS", 'F'}, + {"01&NBV", 'F'}, + {"01&NC", 'F'}, + {"01&NEN", 'F'}, + {"01&NF(", 'F'}, + {"01&NK(", 'F'}, + {"01&NK1", 'F'}, + {"01&NKF", 'F'}, + {"01&NKN", 'F'}, + {"01&NKS", 'F'}, + {"01&NKV", 'F'}, + {"01&NO(", 'F'}, + {"01&NOF", 'F'}, + {"01&NOS", 'F'}, + {"01&NOV", 'F'}, + {"01&NTN", 'F'}, + {"01&NU", 'F'}, + {"01&NU(", 'F'}, + {"01&NU;", 'F'}, + {"01&NUC", 'F'}, + {"01&NUE", 'F'}, + {"01&S", 'F'}, + {"01&S&(", 'F'}, + {"01&S&1", 'F'}, + {"01&S&F", 'F'}, + {"01&S&N", 'F'}, + {"01&S&S", 'F'}, + {"01&S&V", 'F'}, + {"01&S)&", 'F'}, + {"01&S))", 'F'}, + {"01&S)U", 'F'}, + {"01&S1", 'F'}, + {"01&S1;", 'F'}, + {"01&S1C", 'F'}, + {"01&S1O", 'F'}, + {"01&S;", 'F'}, + {"01&S;C", 'F'}, + {"01&S;E", 'F'}, + {"01&S;T", 'F'}, + {"01&SB(", 'F'}, + {"01&SB1", 'F'}, + {"01&SBF", 'F'}, + {"01&SBN", 'F'}, + {"01&SBS", 'F'}, + {"01&SBV", 'F'}, + {"01&SC", 'F'}, + {"01&SEK", 'F'}, + {"01&SEN", 'F'}, + {"01&SF(", 'F'}, + {"01&SK(", 'F'}, + {"01&SK1", 'F'}, + {"01&SKF", 'F'}, + {"01&SKN", 'F'}, + {"01&SKS", 'F'}, + {"01&SKV", 'F'}, + {"01&SO(", 'F'}, + {"01&SO1", 'F'}, + {"01&SOF", 'F'}, + {"01&SON", 'F'}, + {"01&SOO", 'F'}, + {"01&SOS", 'F'}, + {"01&SOV", 'F'}, + {"01&STN", 'F'}, + {"01&SU", 'F'}, + {"01&SU(", 'F'}, + {"01&SU;", 'F'}, + {"01&SUC", 'F'}, + {"01&SUE", 'F'}, + {"01&SV", 'F'}, + {"01&SV;", 'F'}, + {"01&SVC", 'F'}, + {"01&SVO", 'F'}, + {"01&V", 'F'}, + {"01&V&(", 'F'}, + {"01&V&1", 'F'}, + {"01&V&F", 'F'}, + {"01&V&N", 'F'}, + {"01&V&S", 'F'}, + {"01&V&V", 'F'}, + {"01&V)&", 'F'}, + {"01&V))", 'F'}, + {"01&V)U", 'F'}, + {"01&V;", 'F'}, + {"01&V;C", 'F'}, + {"01&V;E", 'F'}, + {"01&V;T", 'F'}, + {"01&VB(", 'F'}, + {"01&VB1", 'F'}, + {"01&VBF", 'F'}, + {"01&VBN", 'F'}, + {"01&VBS", 'F'}, + {"01&VBV", 'F'}, + {"01&VC", 'F'}, + {"01&VEK", 'F'}, + {"01&VEN", 'F'}, + {"01&VF(", 'F'}, + {"01&VK(", 'F'}, + {"01&VK1", 'F'}, + {"01&VKF", 'F'}, + {"01&VKN", 'F'}, + {"01&VKS", 'F'}, + {"01&VKV", 'F'}, + {"01&VO(", 'F'}, + {"01&VOF", 'F'}, + {"01&VOO", 'F'}, + {"01&VOS", 'F'}, + {"01&VS", 'F'}, + {"01&VS;", 'F'}, + {"01&VSC", 'F'}, + {"01&VSO", 'F'}, + {"01&VTN", 'F'}, + {"01&VU", 'F'}, + {"01&VU(", 'F'}, + {"01&VU;", 'F'}, + {"01&VUC", 'F'}, + {"01&VUE", 'F'}, + {"01((((", 'F'}, + {"01(((E", 'F'}, + {"01(((U", 'F'}, + {"01((EK", 'F'}, + {"01((EN", 'F'}, + {"01((U(", 'F'}, + {"01(EKN", 'F'}, + {"01(ENK", 'F'}, + {"01(U((", 'F'}, + {"01(U(E", 'F'}, + {"01)&((", 'F'}, + {"01)&(1", 'F'}, + {"01)&(E", 'F'}, + {"01)&(F", 'F'}, + {"01)&(N", 'F'}, + {"01)&(S", 'F'}, + {"01)&(V", 'F'}, + {"01)&1", 'F'}, + {"01)&1&", 'F'}, + {"01)&1)", 'F'}, + {"01)&1;", 'F'}, + {"01)&1B", 'F'}, + {"01)&1C", 'F'}, + {"01)&1F", 'F'}, + {"01)&1O", 'F'}, + {"01)&1U", 'F'}, + {"01)&F(", 'F'}, + {"01)&N", 'F'}, + {"01)&N&", 'F'}, + {"01)&N)", 'F'}, + {"01)&N;", 'F'}, + {"01)&NB", 'F'}, + {"01)&NC", 'F'}, + {"01)&NF", 'F'}, + {"01)&NO", 'F'}, + {"01)&NU", 'F'}, + {"01)&S", 'F'}, + {"01)&S&", 'F'}, + {"01)&S)", 'F'}, + {"01)&S;", 'F'}, + {"01)&SB", 'F'}, + {"01)&SC", 'F'}, + {"01)&SF", 'F'}, + {"01)&SO", 'F'}, + {"01)&SU", 'F'}, + {"01)&V", 'F'}, + {"01)&V&", 'F'}, + {"01)&V)", 'F'}, + {"01)&V;", 'F'}, + {"01)&VB", 'F'}, + {"01)&VC", 'F'}, + {"01)&VF", 'F'}, + {"01)&VO", 'F'}, + {"01)&VU", 'F'}, + {"01))&(", 'F'}, + {"01))&1", 'F'}, + {"01))&F", 'F'}, + {"01))&N", 'F'}, + {"01))&S", 'F'}, + {"01))&V", 'F'}, + {"01)))&", 'F'}, + {"01))))", 'F'}, + {"01))),", 'F'}, + {"01)));", 'F'}, + {"01)))B", 'F'}, + {"01)))E", 'F'}, + {"01)))K", 'F'}, + {"01)))O", 'F'}, + {"01)))U", 'F'}, + {"01)),(", 'F'}, + {"01));E", 'F'}, + {"01));T", 'F'}, + {"01))B(", 'F'}, + {"01))B1", 'F'}, + {"01))BF", 'F'}, + {"01))BN", 'F'}, + {"01))BS", 'F'}, + {"01))BV", 'F'}, + {"01))E(", 'F'}, + {"01))E1", 'F'}, + {"01))EF", 'F'}, + {"01))EK", 'F'}, + {"01))EN", 'F'}, + {"01))ES", 'F'}, + {"01))EV", 'F'}, + {"01))K(", 'F'}, + {"01))K1", 'F'}, + {"01))KB", 'F'}, + {"01))KF", 'F'}, + {"01))KN", 'F'}, + {"01))KS", 'F'}, + {"01))KU", 'F'}, + {"01))KV", 'F'}, + {"01))O(", 'F'}, + {"01))O1", 'F'}, + {"01))OF", 'F'}, + {"01))ON", 'F'}, + {"01))OS", 'F'}, + {"01))OV", 'F'}, + {"01))U(", 'F'}, + {"01))UE", 'F'}, + {"01),((", 'F'}, + {"01),(1", 'F'}, + {"01),(F", 'F'}, + {"01),(N", 'F'}, + {"01),(S", 'F'}, + {"01),(V", 'F'}, + {"01);E(", 'F'}, + {"01);E1", 'F'}, + {"01);EF", 'F'}, + {"01);EK", 'F'}, + {"01);EN", 'F'}, + {"01);EO", 'F'}, + {"01);ES", 'F'}, + {"01);EV", 'F'}, + {"01);T(", 'F'}, + {"01);T1", 'F'}, + {"01);TF", 'F'}, + {"01);TK", 'F'}, + {"01);TN", 'F'}, + {"01);TO", 'F'}, + {"01);TS", 'F'}, + {"01);TV", 'F'}, + {"01)B((", 'F'}, + {"01)B(1", 'F'}, + {"01)B(F", 'F'}, + {"01)B(N", 'F'}, + {"01)B(S", 'F'}, + {"01)B(V", 'F'}, + {"01)B1", 'F'}, + {"01)B1&", 'F'}, + {"01)B1;", 'F'}, + {"01)B1C", 'F'}, + {"01)B1K", 'F'}, + {"01)B1N", 'F'}, + {"01)B1O", 'F'}, + {"01)B1U", 'F'}, + {"01)BF(", 'F'}, + {"01)BN", 'F'}, + {"01)BN&", 'F'}, + {"01)BN;", 'F'}, + {"01)BNC", 'F'}, + {"01)BNK", 'F'}, + {"01)BNO", 'F'}, + {"01)BNU", 'F'}, + {"01)BS", 'F'}, + {"01)BS&", 'F'}, + {"01)BS;", 'F'}, + {"01)BSC", 'F'}, + {"01)BSK", 'F'}, + {"01)BSO", 'F'}, + {"01)BSU", 'F'}, + {"01)BV", 'F'}, + {"01)BV&", 'F'}, + {"01)BV;", 'F'}, + {"01)BVC", 'F'}, + {"01)BVK", 'F'}, + {"01)BVO", 'F'}, + {"01)BVU", 'F'}, + {"01)E((", 'F'}, + {"01)E(1", 'F'}, + {"01)E(F", 'F'}, + {"01)E(N", 'F'}, + {"01)E(S", 'F'}, + {"01)E(V", 'F'}, + {"01)E1C", 'F'}, + {"01)E1O", 'F'}, + {"01)EF(", 'F'}, + {"01)EK(", 'F'}, + {"01)EK1", 'F'}, + {"01)EKF", 'F'}, + {"01)EKN", 'F'}, + {"01)EKS", 'F'}, + {"01)EKV", 'F'}, + {"01)ENC", 'F'}, + {"01)ENO", 'F'}, + {"01)ESC", 'F'}, + {"01)ESO", 'F'}, + {"01)EVC", 'F'}, + {"01)EVO", 'F'}, + {"01)K((", 'F'}, + {"01)K(1", 'F'}, + {"01)K(F", 'F'}, + {"01)K(N", 'F'}, + {"01)K(S", 'F'}, + {"01)K(V", 'F'}, + {"01)K1&", 'F'}, + {"01)K1;", 'F'}, + {"01)K1B", 'F'}, + {"01)K1E", 'F'}, + {"01)K1O", 'F'}, + {"01)K1U", 'F'}, + {"01)KB(", 'F'}, + {"01)KB1", 'F'}, + {"01)KBF", 'F'}, + {"01)KBN", 'F'}, + {"01)KBS", 'F'}, + {"01)KBV", 'F'}, + {"01)KF(", 'F'}, + {"01)KN&", 'F'}, + {"01)KN;", 'F'}, + {"01)KNB", 'F'}, + {"01)KNE", 'F'}, + {"01)KNK", 'F'}, + {"01)KNU", 'F'}, + {"01)KS&", 'F'}, + {"01)KS;", 'F'}, + {"01)KSB", 'F'}, + {"01)KSE", 'F'}, + {"01)KSO", 'F'}, + {"01)KSU", 'F'}, + {"01)KUE", 'F'}, + {"01)KV&", 'F'}, + {"01)KV;", 'F'}, + {"01)KVB", 'F'}, + {"01)KVE", 'F'}, + {"01)KVO", 'F'}, + {"01)KVU", 'F'}, + {"01)O((", 'F'}, + {"01)O(1", 'F'}, + {"01)O(E", 'F'}, + {"01)O(F", 'F'}, + {"01)O(N", 'F'}, + {"01)O(S", 'F'}, + {"01)O(V", 'F'}, + {"01)O1", 'F'}, + {"01)O1&", 'F'}, + {"01)O1)", 'F'}, + {"01)O1;", 'F'}, + {"01)O1B", 'F'}, + {"01)O1C", 'F'}, + {"01)O1K", 'F'}, + {"01)O1O", 'F'}, + {"01)O1U", 'F'}, + {"01)OF(", 'F'}, + {"01)ON", 'F'}, + {"01)ON&", 'F'}, + {"01)ON)", 'F'}, + {"01)ON;", 'F'}, + {"01)ONB", 'F'}, + {"01)ONC", 'F'}, + {"01)ONK", 'F'}, + {"01)ONO", 'F'}, + {"01)ONU", 'F'}, + {"01)OS", 'F'}, + {"01)OS&", 'F'}, + {"01)OS)", 'F'}, + {"01)OS;", 'F'}, + {"01)OSB", 'F'}, + {"01)OSC", 'F'}, + {"01)OSK", 'F'}, + {"01)OSO", 'F'}, + {"01)OSU", 'F'}, + {"01)OV", 'F'}, + {"01)OV&", 'F'}, + {"01)OV)", 'F'}, + {"01)OV;", 'F'}, + {"01)OVB", 'F'}, + {"01)OVC", 'F'}, + {"01)OVK", 'F'}, + {"01)OVO", 'F'}, + {"01)OVU", 'F'}, + {"01)U((", 'F'}, + {"01)U(E", 'F'}, + {"01)UE(", 'F'}, + {"01)UE1", 'F'}, + {"01)UEF", 'F'}, + {"01)UEK", 'F'}, + {"01)UEN", 'F'}, + {"01)UES", 'F'}, + {"01)UEV", 'F'}, + {"01,(((", 'F'}, + {"01,((1", 'F'}, + {"01,((E", 'F'}, + {"01,((F", 'F'}, + {"01,((N", 'F'}, + {"01,((S", 'F'}, + {"01,((V", 'F'}, + {"01,(1)", 'F'}, + {"01,(1O", 'F'}, + {"01,(E(", 'F'}, + {"01,(E1", 'F'}, + {"01,(EF", 'F'}, + {"01,(EK", 'F'}, + {"01,(EN", 'F'}, + {"01,(ES", 'F'}, + {"01,(EV", 'F'}, + {"01,(F(", 'F'}, + {"01,(N)", 'F'}, + {"01,(NO", 'F'}, + {"01,(S)", 'F'}, + {"01,(SO", 'F'}, + {"01,(V)", 'F'}, + {"01,(VO", 'F'}, + {"01,F((", 'F'}, + {"01,F()", 'F'}, + {"01,F(1", 'F'}, + {"01,F(F", 'F'}, + {"01,F(N", 'F'}, + {"01,F(S", 'F'}, + {"01,F(T", 'F'}, + {"01,F(V", 'F'}, + {"01,V))", 'F'}, + {"01,V),", 'F'}, + {"01,V)O", 'F'}, + {"01,VB(", 'F'}, + {"01,VB1", 'F'}, + {"01,VBF", 'F'}, + {"01,VBN", 'F'}, + {"01,VBS", 'F'}, + {"01,VBV", 'F'}, + {"01,VO(", 'F'}, + {"01,VOF", 'F'}, + {"01,VOS", 'F'}, + {"01,VUE", 'F'}, + {"01;E((", 'F'}, + {"01;E(1", 'F'}, + {"01;E(E", 'F'}, + {"01;E(F", 'F'}, + {"01;E(N", 'F'}, + {"01;E(S", 'F'}, + {"01;E(V", 'F'}, + {"01;E1,", 'F'}, + {"01;E1;", 'F'}, + {"01;E1C", 'F'}, + {"01;E1O", 'F'}, + {"01;E1T", 'F'}, + {"01;EF(", 'F'}, + {"01;EK(", 'F'}, + {"01;EK1", 'F'}, + {"01;EKF", 'F'}, + {"01;EKN", 'F'}, + {"01;EKO", 'F'}, + {"01;EKS", 'F'}, + {"01;EKV", 'F'}, + {"01;EN,", 'F'}, + {"01;EN;", 'F'}, + {"01;ENC", 'F'}, + {"01;ENK", 'F'}, + {"01;ENO", 'F'}, + {"01;ENT", 'F'}, + {"01;EO(", 'F'}, + {"01;ES,", 'F'}, + {"01;ES;", 'F'}, + {"01;ESC", 'F'}, + {"01;ESO", 'F'}, + {"01;EST", 'F'}, + {"01;EV,", 'F'}, + {"01;EV;", 'F'}, + {"01;EVC", 'F'}, + {"01;EVO", 'F'}, + {"01;EVT", 'F'}, + {"01;N:T", 'F'}, + {"01;T((", 'F'}, + {"01;T(1", 'F'}, + {"01;T(E", 'F'}, + {"01;T(F", 'F'}, + {"01;T(N", 'F'}, + {"01;T(S", 'F'}, + {"01;T(V", 'F'}, + {"01;T1,", 'F'}, + {"01;T1;", 'F'}, + {"01;T1C", 'F'}, + {"01;T1F", 'F'}, + {"01;T1O", 'F'}, + {"01;T1T", 'F'}, + {"01;T;", 'F'}, + {"01;T;C", 'F'}, + {"01;TF(", 'F'}, + {"01;TK(", 'F'}, + {"01;TK1", 'F'}, + {"01;TKF", 'F'}, + {"01;TKK", 'F'}, + {"01;TKN", 'F'}, + {"01;TKO", 'F'}, + {"01;TKS", 'F'}, + {"01;TKV", 'F'}, + {"01;TN(", 'F'}, + {"01;TN,", 'F'}, + {"01;TN1", 'F'}, + {"01;TN;", 'F'}, + {"01;TNC", 'F'}, + {"01;TNE", 'F'}, + {"01;TNF", 'F'}, + {"01;TNK", 'F'}, + {"01;TNN", 'F'}, + {"01;TNO", 'F'}, + {"01;TNS", 'F'}, + {"01;TNT", 'F'}, + {"01;TNV", 'F'}, + {"01;TO(", 'F'}, + {"01;TS,", 'F'}, + {"01;TS;", 'F'}, + {"01;TSC", 'F'}, + {"01;TSF", 'F'}, + {"01;TSO", 'F'}, + {"01;TST", 'F'}, + {"01;TT(", 'F'}, + {"01;TT1", 'F'}, + {"01;TTF", 'F'}, + {"01;TTN", 'F'}, + {"01;TTS", 'F'}, + {"01;TTV", 'F'}, + {"01;TV,", 'F'}, + {"01;TV;", 'F'}, + {"01;TVC", 'F'}, + {"01;TVF", 'F'}, + {"01;TVO", 'F'}, + {"01;TVT", 'F'}, + {"01A(((", 'F'}, + {"01A((1", 'F'}, + {"01A((F", 'F'}, + {"01A((N", 'F'}, + {"01A((S", 'F'}, + {"01A((V", 'F'}, + {"01A(F(", 'F'}, + {"01A(N)", 'F'}, + {"01A(NO", 'F'}, + {"01A(S)", 'F'}, + {"01A(SO", 'F'}, + {"01A(V)", 'F'}, + {"01A(VO", 'F'}, + {"01AF((", 'F'}, + {"01AF()", 'F'}, + {"01AF(1", 'F'}, + {"01AF(F", 'F'}, + {"01AF(N", 'F'}, + {"01AF(S", 'F'}, + {"01AF(V", 'F'}, + {"01ASO(", 'F'}, + {"01ASO1", 'F'}, + {"01ASOF", 'F'}, + {"01ASON", 'F'}, + {"01ASOS", 'F'}, + {"01ASOV", 'F'}, + {"01ASUE", 'F'}, + {"01ATO(", 'F'}, + {"01ATO1", 'F'}, + {"01ATOF", 'F'}, + {"01ATON", 'F'}, + {"01ATOS", 'F'}, + {"01ATOV", 'F'}, + {"01ATUE", 'F'}, + {"01AVO(", 'F'}, + {"01AVOF", 'F'}, + {"01AVOS", 'F'}, + {"01AVUE", 'F'}, + {"01B(((", 'F'}, + {"01B((1", 'F'}, + {"01B((F", 'F'}, + {"01B((N", 'F'}, + {"01B((S", 'F'}, + {"01B((V", 'F'}, + {"01B(1)", 'F'}, + {"01B(1O", 'F'}, + {"01B(F(", 'F'}, + {"01B(N)", 'F'}, + {"01B(NO", 'F'}, + {"01B(S)", 'F'}, + {"01B(SO", 'F'}, + {"01B(V)", 'F'}, + {"01B(VO", 'F'}, + {"01B1", 'F'}, + {"01B1&(", 'F'}, + {"01B1&1", 'F'}, + {"01B1&F", 'F'}, + {"01B1&N", 'F'}, + {"01B1&S", 'F'}, + {"01B1&V", 'F'}, + {"01B1,(", 'F'}, + {"01B1,F", 'F'}, + {"01B1,V", 'F'}, + {"01B1;", 'F'}, + {"01B1;C", 'F'}, + {"01B1B(", 'F'}, + {"01B1B1", 'F'}, + {"01B1BF", 'F'}, + {"01B1BN", 'F'}, + {"01B1BS", 'F'}, + {"01B1BV", 'F'}, + {"01B1C", 'F'}, + {"01B1K(", 'F'}, + {"01B1K1", 'F'}, + {"01B1KF", 'F'}, + {"01B1KN", 'F'}, + {"01B1KS", 'F'}, + {"01B1KV", 'F'}, + {"01B1O(", 'F'}, + {"01B1OF", 'F'}, + {"01B1OS", 'F'}, + {"01B1OV", 'F'}, + {"01B1U(", 'F'}, + {"01B1UE", 'F'}, + {"01BE((", 'F'}, + {"01BE(1", 'F'}, + {"01BE(F", 'F'}, + {"01BE(N", 'F'}, + {"01BE(S", 'F'}, + {"01BE(V", 'F'}, + {"01BEK(", 'F'}, + {"01BF((", 'F'}, + {"01BF()", 'F'}, + {"01BF(1", 'F'}, + {"01BF(F", 'F'}, + {"01BF(N", 'F'}, + {"01BF(S", 'F'}, + {"01BF(V", 'F'}, + {"01BN", 'F'}, + {"01BN&(", 'F'}, + {"01BN&1", 'F'}, + {"01BN&F", 'F'}, + {"01BN&N", 'F'}, + {"01BN&S", 'F'}, + {"01BN&V", 'F'}, + {"01BN,(", 'F'}, + {"01BN,F", 'F'}, + {"01BN,V", 'F'}, + {"01BN;", 'F'}, + {"01BN;C", 'F'}, + {"01BNB(", 'F'}, + {"01BNB1", 'F'}, + {"01BNBF", 'F'}, + {"01BNBN", 'F'}, + {"01BNBS", 'F'}, + {"01BNBV", 'F'}, + {"01BNC", 'F'}, + {"01BNK(", 'F'}, + {"01BNK1", 'F'}, + {"01BNKF", 'F'}, + {"01BNKN", 'F'}, + {"01BNKS", 'F'}, + {"01BNKV", 'F'}, + {"01BNO(", 'F'}, + {"01BNOF", 'F'}, + {"01BNOS", 'F'}, + {"01BNOV", 'F'}, + {"01BNU(", 'F'}, + {"01BNUE", 'F'}, + {"01BS", 'F'}, + {"01BS&(", 'F'}, + {"01BS&1", 'F'}, + {"01BS&F", 'F'}, + {"01BS&N", 'F'}, + {"01BS&S", 'F'}, + {"01BS&V", 'F'}, + {"01BS,(", 'F'}, + {"01BS,F", 'F'}, + {"01BS,V", 'F'}, + {"01BS;", 'F'}, + {"01BS;C", 'F'}, + {"01BSB(", 'F'}, + {"01BSB1", 'F'}, + {"01BSBF", 'F'}, + {"01BSBN", 'F'}, + {"01BSBS", 'F'}, + {"01BSBV", 'F'}, + {"01BSC", 'F'}, + {"01BSK(", 'F'}, + {"01BSK1", 'F'}, + {"01BSKF", 'F'}, + {"01BSKN", 'F'}, + {"01BSKS", 'F'}, + {"01BSKV", 'F'}, + {"01BSO(", 'F'}, + {"01BSO1", 'F'}, + {"01BSOF", 'F'}, + {"01BSON", 'F'}, + {"01BSOS", 'F'}, + {"01BSOV", 'F'}, + {"01BSU(", 'F'}, + {"01BSUE", 'F'}, + {"01BV", 'F'}, + {"01BV&(", 'F'}, + {"01BV&1", 'F'}, + {"01BV&F", 'F'}, + {"01BV&N", 'F'}, + {"01BV&S", 'F'}, + {"01BV&V", 'F'}, + {"01BV,(", 'F'}, + {"01BV,1", 'F'}, + {"01BV,F", 'F'}, + {"01BV,N", 'F'}, + {"01BV,S", 'F'}, + {"01BV,V", 'F'}, + {"01BV;", 'F'}, + {"01BV;C", 'F'}, + {"01BVB(", 'F'}, + {"01BVB1", 'F'}, + {"01BVBF", 'F'}, + {"01BVBN", 'F'}, + {"01BVBS", 'F'}, + {"01BVBV", 'F'}, + {"01BVC", 'F'}, + {"01BVK(", 'F'}, + {"01BVK1", 'F'}, + {"01BVKF", 'F'}, + {"01BVKN", 'F'}, + {"01BVKS", 'F'}, + {"01BVKV", 'F'}, + {"01BVO(", 'F'}, + {"01BVOF", 'F'}, + {"01BVOS", 'F'}, + {"01BVU(", 'F'}, + {"01BVUE", 'F'}, + {"01C", 'F'}, + {"01E(((", 'F'}, + {"01E((1", 'F'}, + {"01E((F", 'F'}, + {"01E((N", 'F'}, + {"01E((S", 'F'}, + {"01E((V", 'F'}, + {"01E(1)", 'F'}, + {"01E(1O", 'F'}, + {"01E(F(", 'F'}, + {"01E(N)", 'F'}, + {"01E(NO", 'F'}, + {"01E(S)", 'F'}, + {"01E(SO", 'F'}, + {"01E(V)", 'F'}, + {"01E(VO", 'F'}, + {"01E1C", 'F'}, + {"01E1O(", 'F'}, + {"01E1OF", 'F'}, + {"01E1OS", 'F'}, + {"01E1OV", 'F'}, + {"01E1UE", 'F'}, + {"01EF((", 'F'}, + {"01EF()", 'F'}, + {"01EF(1", 'F'}, + {"01EF(F", 'F'}, + {"01EF(N", 'F'}, + {"01EF(S", 'F'}, + {"01EF(V", 'F'}, + {"01EK((", 'F'}, + {"01EK(1", 'F'}, + {"01EK(E", 'F'}, + {"01EK(F", 'F'}, + {"01EK(N", 'F'}, + {"01EK(S", 'F'}, + {"01EK(V", 'F'}, + {"01EK1C", 'F'}, + {"01EK1O", 'F'}, + {"01EK1U", 'F'}, + {"01EKF(", 'F'}, + {"01EKNC", 'F'}, + {"01EKNE", 'F'}, + {"01EKNU", 'F'}, + {"01EKOK", 'F'}, + {"01EKSC", 'F'}, + {"01EKSO", 'F'}, + {"01EKSU", 'F'}, + {"01EKU(", 'F'}, + {"01EKU1", 'F'}, + {"01EKUE", 'F'}, + {"01EKUF", 'F'}, + {"01EKUN", 'F'}, + {"01EKUS", 'F'}, + {"01EKUV", 'F'}, + {"01EKVC", 'F'}, + {"01EKVO", 'F'}, + {"01EKVU", 'F'}, + {"01ENC", 'F'}, + {"01ENEN", 'F'}, + {"01ENO(", 'F'}, + {"01ENOF", 'F'}, + {"01ENOS", 'F'}, + {"01ENOV", 'F'}, + {"01ENUE", 'F'}, + {"01EOKN", 'F'}, + {"01ESC", 'F'}, + {"01ESO(", 'F'}, + {"01ESO1", 'F'}, + {"01ESOF", 'F'}, + {"01ESON", 'F'}, + {"01ESOS", 'F'}, + {"01ESOV", 'F'}, + {"01ESUE", 'F'}, + {"01EU((", 'F'}, + {"01EU(1", 'F'}, + {"01EU(F", 'F'}, + {"01EU(N", 'F'}, + {"01EU(S", 'F'}, + {"01EU(V", 'F'}, + {"01EU1,", 'F'}, + {"01EU1C", 'F'}, + {"01EU1O", 'F'}, + {"01EUEF", 'F'}, + {"01EUEK", 'F'}, + {"01EUF(", 'F'}, + {"01EUN,", 'F'}, + {"01EUNC", 'F'}, + {"01EUNO", 'F'}, + {"01EUS,", 'F'}, + {"01EUSC", 'F'}, + {"01EUSO", 'F'}, + {"01EUV,", 'F'}, + {"01EUVC", 'F'}, + {"01EUVO", 'F'}, + {"01EVC", 'F'}, + {"01EVO(", 'F'}, + {"01EVOF", 'F'}, + {"01EVOS", 'F'}, + {"01EVUE", 'F'}, + {"01F(((", 'F'}, + {"01F(()", 'F'}, + {"01F((1", 'F'}, + {"01F((F", 'F'}, + {"01F((N", 'F'}, + {"01F((S", 'F'}, + {"01F((V", 'F'}, + {"01F())", 'F'}, + {"01F()1", 'F'}, + {"01F()F", 'F'}, + {"01F()K", 'F'}, + {"01F()N", 'F'}, + {"01F()O", 'F'}, + {"01F()S", 'F'}, + {"01F()U", 'F'}, + {"01F()V", 'F'}, + {"01F(1)", 'F'}, + {"01F(1N", 'F'}, + {"01F(1O", 'F'}, + {"01F(F(", 'F'}, + {"01F(N)", 'F'}, + {"01F(N,", 'F'}, + {"01F(NO", 'F'}, + {"01F(S)", 'F'}, + {"01F(SO", 'F'}, + {"01F(V)", 'F'}, + {"01F(VO", 'F'}, + {"01K(((", 'F'}, + {"01K((1", 'F'}, + {"01K((F", 'F'}, + {"01K((N", 'F'}, + {"01K((S", 'F'}, + {"01K((V", 'F'}, + {"01K(1)", 'F'}, + {"01K(1O", 'F'}, + {"01K(F(", 'F'}, + {"01K(N)", 'F'}, + {"01K(NO", 'F'}, + {"01K(S)", 'F'}, + {"01K(SO", 'F'}, + {"01K(V)", 'F'}, + {"01K(VO", 'F'}, + {"01K)&(", 'F'}, + {"01K)&1", 'F'}, + {"01K)&F", 'F'}, + {"01K)&N", 'F'}, + {"01K)&S", 'F'}, + {"01K)&V", 'F'}, + {"01K))&", 'F'}, + {"01K)))", 'F'}, + {"01K));", 'F'}, + {"01K))B", 'F'}, + {"01K))E", 'F'}, + {"01K))K", 'F'}, + {"01K))O", 'F'}, + {"01K))U", 'F'}, + {"01K);E", 'F'}, + {"01K);T", 'F'}, + {"01K)B(", 'F'}, + {"01K)B1", 'F'}, + {"01K)BF", 'F'}, + {"01K)BN", 'F'}, + {"01K)BS", 'F'}, + {"01K)BV", 'F'}, + {"01K)E(", 'F'}, + {"01K)E1", 'F'}, + {"01K)EF", 'F'}, + {"01K)EK", 'F'}, + {"01K)EN", 'F'}, + {"01K)ES", 'F'}, + {"01K)EV", 'F'}, + {"01K)OF", 'F'}, + {"01K)UE", 'F'}, + {"01K1", 'F'}, + {"01K1&(", 'F'}, + {"01K1&1", 'F'}, + {"01K1&F", 'F'}, + {"01K1&N", 'F'}, + {"01K1&S", 'F'}, + {"01K1&V", 'F'}, + {"01K1;", 'F'}, + {"01K1;C", 'F'}, + {"01K1;E", 'F'}, + {"01K1;T", 'F'}, + {"01K1B(", 'F'}, + {"01K1B1", 'F'}, + {"01K1BF", 'F'}, + {"01K1BN", 'F'}, + {"01K1BS", 'F'}, + {"01K1BV", 'F'}, + {"01K1C", 'F'}, + {"01K1E(", 'F'}, + {"01K1E1", 'F'}, + {"01K1EF", 'F'}, + {"01K1EK", 'F'}, + {"01K1EN", 'F'}, + {"01K1ES", 'F'}, + {"01K1EV", 'F'}, + {"01K1O(", 'F'}, + {"01K1OF", 'F'}, + {"01K1OS", 'F'}, + {"01K1OV", 'F'}, + {"01K1U(", 'F'}, + {"01K1UE", 'F'}, + {"01KF((", 'F'}, + {"01KF()", 'F'}, + {"01KF(1", 'F'}, + {"01KF(F", 'F'}, + {"01KF(N", 'F'}, + {"01KF(S", 'F'}, + {"01KF(V", 'F'}, + {"01KN", 'F'}, + {"01KN&(", 'F'}, + {"01KN&1", 'F'}, + {"01KN&F", 'F'}, + {"01KN&N", 'F'}, + {"01KN&S", 'F'}, + {"01KN&V", 'F'}, + {"01KN;", 'F'}, + {"01KN;C", 'F'}, + {"01KN;E", 'F'}, + {"01KN;T", 'F'}, + {"01KNB(", 'F'}, + {"01KNB1", 'F'}, + {"01KNBF", 'F'}, + {"01KNBN", 'F'}, + {"01KNBS", 'F'}, + {"01KNBV", 'F'}, + {"01KNC", 'F'}, + {"01KNE(", 'F'}, + {"01KNE1", 'F'}, + {"01KNEF", 'F'}, + {"01KNEN", 'F'}, + {"01KNES", 'F'}, + {"01KNEV", 'F'}, + {"01KNU(", 'F'}, + {"01KNUE", 'F'}, + {"01KS", 'F'}, + {"01KS&(", 'F'}, + {"01KS&1", 'F'}, + {"01KS&F", 'F'}, + {"01KS&N", 'F'}, + {"01KS&S", 'F'}, + {"01KS&V", 'F'}, + {"01KS;", 'F'}, + {"01KS;C", 'F'}, + {"01KS;E", 'F'}, + {"01KS;T", 'F'}, + {"01KSB(", 'F'}, + {"01KSB1", 'F'}, + {"01KSBF", 'F'}, + {"01KSBN", 'F'}, + {"01KSBS", 'F'}, + {"01KSBV", 'F'}, + {"01KSC", 'F'}, + {"01KSE(", 'F'}, + {"01KSE1", 'F'}, + {"01KSEF", 'F'}, + {"01KSEK", 'F'}, + {"01KSEN", 'F'}, + {"01KSES", 'F'}, + {"01KSEV", 'F'}, + {"01KSO(", 'F'}, + {"01KSO1", 'F'}, + {"01KSOF", 'F'}, + {"01KSON", 'F'}, + {"01KSOS", 'F'}, + {"01KSOV", 'F'}, + {"01KSU(", 'F'}, + {"01KSUE", 'F'}, + {"01KUE(", 'F'}, + {"01KUE1", 'F'}, + {"01KUEF", 'F'}, + {"01KUEK", 'F'}, + {"01KUEN", 'F'}, + {"01KUES", 'F'}, + {"01KUEV", 'F'}, + {"01KV", 'F'}, + {"01KV&(", 'F'}, + {"01KV&1", 'F'}, + {"01KV&F", 'F'}, + {"01KV&N", 'F'}, + {"01KV&S", 'F'}, + {"01KV&V", 'F'}, + {"01KV;", 'F'}, + {"01KV;C", 'F'}, + {"01KV;E", 'F'}, + {"01KV;T", 'F'}, + {"01KVB(", 'F'}, + {"01KVB1", 'F'}, + {"01KVBF", 'F'}, + {"01KVBN", 'F'}, + {"01KVBS", 'F'}, + {"01KVBV", 'F'}, + {"01KVC", 'F'}, + {"01KVE(", 'F'}, + {"01KVE1", 'F'}, + {"01KVEF", 'F'}, + {"01KVEK", 'F'}, + {"01KVEN", 'F'}, + {"01KVES", 'F'}, + {"01KVEV", 'F'}, + {"01KVO(", 'F'}, + {"01KVOF", 'F'}, + {"01KVOS", 'F'}, + {"01KVU(", 'F'}, + {"01KVUE", 'F'}, + {"01N&F(", 'F'}, + {"01N(((", 'F'}, + {"01N((1", 'F'}, + {"01N((F", 'F'}, + {"01N((N", 'F'}, + {"01N((S", 'F'}, + {"01N((V", 'F'}, + {"01N(1)", 'F'}, + {"01N(1O", 'F'}, + {"01N(F(", 'F'}, + {"01N(S)", 'F'}, + {"01N(SO", 'F'}, + {"01N(V)", 'F'}, + {"01N(VO", 'F'}, + {"01N)))", 'F'}, + {"01N))N", 'F'}, + {"01N))U", 'F'}, + {"01N)UE", 'F'}, + {"01N,F(", 'F'}, + {"01NE((", 'F'}, + {"01NE(1", 'F'}, + {"01NE(F", 'F'}, + {"01NE(N", 'F'}, + {"01NE(S", 'F'}, + {"01NE(V", 'F'}, + {"01NE1C", 'F'}, + {"01NE1O", 'F'}, + {"01NEF(", 'F'}, + {"01NENC", 'F'}, + {"01NENO", 'F'}, + {"01NESC", 'F'}, + {"01NESO", 'F'}, + {"01NEVC", 'F'}, + {"01NEVO", 'F'}, + {"01NF((", 'F'}, + {"01NF()", 'F'}, + {"01NF(1", 'F'}, + {"01NF(F", 'F'}, + {"01NF(N", 'F'}, + {"01NF(S", 'F'}, + {"01NF(V", 'F'}, + {"01NO((", 'F'}, + {"01NO(1", 'F'}, + {"01NO(F", 'F'}, + {"01NO(N", 'F'}, + {"01NO(S", 'F'}, + {"01NO(V", 'F'}, + {"01NOF(", 'F'}, + {"01NOS(", 'F'}, + {"01NOS1", 'F'}, + {"01NOSF", 'F'}, + {"01NOSO", 'F'}, + {"01NOSU", 'F'}, + {"01NOSV", 'F'}, + {"01NOV(", 'F'}, + {"01NOVF", 'F'}, + {"01NOVO", 'F'}, + {"01NOVS", 'F'}, + {"01NOVU", 'F'}, + {"01NU((", 'F'}, + {"01NU(E", 'F'}, + {"01NUE", 'F'}, + {"01NUE(", 'F'}, + {"01NUE1", 'F'}, + {"01NUE;", 'F'}, + {"01NUEC", 'F'}, + {"01NUEF", 'F'}, + {"01NUEK", 'F'}, + {"01NUEN", 'F'}, + {"01NUES", 'F'}, + {"01NUEV", 'F'}, + {"01O(((", 'F'}, + {"01O((1", 'F'}, + {"01O((E", 'F'}, + {"01O((F", 'F'}, + {"01O((N", 'F'}, + {"01O((O", 'F'}, + {"01O((S", 'F'}, + {"01O((T", 'F'}, + {"01O((V", 'F'}, + {"01O(1&", 'F'}, + {"01O(1)", 'F'}, + {"01O(1,", 'F'}, + {"01O(1O", 'F'}, + {"01O(E(", 'F'}, + {"01O(E1", 'F'}, + {"01O(EE", 'F'}, + {"01O(EF", 'F'}, + {"01O(EK", 'F'}, + {"01O(EN", 'F'}, + {"01O(ES", 'F'}, + {"01O(EV", 'F'}, + {"01O(F(", 'F'}, + {"01O(N&", 'F'}, + {"01O(N)", 'F'}, + {"01O(N,", 'F'}, + {"01O(NO", 'F'}, + {"01O(O(", 'F'}, + {"01O(O1", 'F'}, + {"01O(OF", 'F'}, + {"01O(ON", 'F'}, + {"01O(OS", 'F'}, + {"01O(OV", 'F'}, + {"01O(S&", 'F'}, + {"01O(S)", 'F'}, + {"01O(S,", 'F'}, + {"01O(SO", 'F'}, + {"01O(T(", 'F'}, + {"01O(V&", 'F'}, + {"01O(V)", 'F'}, + {"01O(V,", 'F'}, + {"01O(VO", 'F'}, + {"01OF((", 'F'}, + {"01OF()", 'F'}, + {"01OF(1", 'F'}, + {"01OF(E", 'F'}, + {"01OF(F", 'F'}, + {"01OF(N", 'F'}, + {"01OF(S", 'F'}, + {"01OF(V", 'F'}, + {"01OK&(", 'F'}, + {"01OK&1", 'F'}, + {"01OK&F", 'F'}, + {"01OK&N", 'F'}, + {"01OK&S", 'F'}, + {"01OK&V", 'F'}, + {"01OK((", 'F'}, + {"01OK(1", 'F'}, + {"01OK(F", 'F'}, + {"01OK(N", 'F'}, + {"01OK(S", 'F'}, + {"01OK(V", 'F'}, + {"01OK1C", 'F'}, + {"01OK1O", 'F'}, + {"01OKF(", 'F'}, + {"01OKNC", 'F'}, + {"01OKO(", 'F'}, + {"01OKO1", 'F'}, + {"01OKOF", 'F'}, + {"01OKON", 'F'}, + {"01OKOS", 'F'}, + {"01OKOV", 'F'}, + {"01OKSC", 'F'}, + {"01OKSO", 'F'}, + {"01OKVC", 'F'}, + {"01OKVO", 'F'}, + {"01ONSU", 'F'}, + {"01OS&(", 'F'}, + {"01OS&1", 'F'}, + {"01OS&E", 'F'}, + {"01OS&F", 'F'}, + {"01OS&K", 'F'}, + {"01OS&N", 'F'}, + {"01OS&S", 'F'}, + {"01OS&U", 'F'}, + {"01OS&V", 'F'}, + {"01OS((", 'F'}, + {"01OS(E", 'F'}, + {"01OS(U", 'F'}, + {"01OS)&", 'F'}, + {"01OS))", 'F'}, + {"01OS),", 'F'}, + {"01OS);", 'F'}, + {"01OS)B", 'F'}, + {"01OS)E", 'F'}, + {"01OS)K", 'F'}, + {"01OS)O", 'F'}, + {"01OS)U", 'F'}, + {"01OS,(", 'F'}, + {"01OS,F", 'F'}, + {"01OS,V", 'F'}, + {"01OS1(", 'F'}, + {"01OS1F", 'F'}, + {"01OS1N", 'F'}, + {"01OS1S", 'F'}, + {"01OS1U", 'F'}, + {"01OS1V", 'F'}, + {"01OS;", 'F'}, + {"01OS;C", 'F'}, + {"01OS;E", 'F'}, + {"01OS;N", 'F'}, + {"01OS;T", 'F'}, + {"01OSA(", 'F'}, + {"01OSAF", 'F'}, + {"01OSAS", 'F'}, + {"01OSAT", 'F'}, + {"01OSAV", 'F'}, + {"01OSB(", 'F'}, + {"01OSB1", 'F'}, + {"01OSBE", 'F'}, + {"01OSBF", 'F'}, + {"01OSBN", 'F'}, + {"01OSBS", 'F'}, + {"01OSBV", 'F'}, + {"01OSC", 'F'}, + {"01OSE(", 'F'}, + {"01OSE1", 'F'}, + {"01OSEF", 'F'}, + {"01OSEK", 'F'}, + {"01OSEN", 'F'}, + {"01OSEO", 'F'}, + {"01OSES", 'F'}, + {"01OSEU", 'F'}, + {"01OSEV", 'F'}, + {"01OSF(", 'F'}, + {"01OSK(", 'F'}, + {"01OSK)", 'F'}, + {"01OSK1", 'F'}, + {"01OSKB", 'F'}, + {"01OSKF", 'F'}, + {"01OSKN", 'F'}, + {"01OSKS", 'F'}, + {"01OSKU", 'F'}, + {"01OSKV", 'F'}, + {"01OSO(", 'F'}, + {"01OSO1", 'F'}, + {"01OSOF", 'F'}, + {"01OSOK", 'F'}, + {"01OSON", 'F'}, + {"01OSOS", 'F'}, + {"01OSOT", 'F'}, + {"01OSOU", 'F'}, + {"01OSOV", 'F'}, + {"01OSU", 'F'}, + {"01OSU(", 'F'}, + {"01OSU1", 'F'}, + {"01OSU;", 'F'}, + {"01OSUC", 'F'}, + {"01OSUE", 'F'}, + {"01OSUF", 'F'}, + {"01OSUK", 'F'}, + {"01OSUN", 'F'}, + {"01OSUO", 'F'}, + {"01OSUS", 'F'}, + {"01OSUT", 'F'}, + {"01OSUV", 'F'}, + {"01OSV(", 'F'}, + {"01OSVF", 'F'}, + {"01OSVO", 'F'}, + {"01OSVS", 'F'}, + {"01OSVU", 'F'}, + {"01OT((", 'F'}, + {"01OT(1", 'F'}, + {"01OT(F", 'F'}, + {"01OT(N", 'F'}, + {"01OT(S", 'F'}, + {"01OT(V", 'F'}, + {"01OU((", 'F'}, + {"01OU(E", 'F'}, + {"01OUEK", 'F'}, + {"01OUEN", 'F'}, + {"01OV", 'F'}, + {"01OV&(", 'F'}, + {"01OV&1", 'F'}, + {"01OV&E", 'F'}, + {"01OV&F", 'F'}, + {"01OV&K", 'F'}, + {"01OV&N", 'F'}, + {"01OV&S", 'F'}, + {"01OV&U", 'F'}, + {"01OV&V", 'F'}, + {"01OV((", 'F'}, + {"01OV(E", 'F'}, + {"01OV(U", 'F'}, + {"01OV)&", 'F'}, + {"01OV))", 'F'}, + {"01OV),", 'F'}, + {"01OV);", 'F'}, + {"01OV)B", 'F'}, + {"01OV)E", 'F'}, + {"01OV)K", 'F'}, + {"01OV)O", 'F'}, + {"01OV)U", 'F'}, + {"01OV,(", 'F'}, + {"01OV,1", 'F'}, + {"01OV,F", 'F'}, + {"01OV,N", 'F'}, + {"01OV,S", 'F'}, + {"01OV,V", 'F'}, + {"01OV;", 'F'}, + {"01OV;C", 'F'}, + {"01OV;E", 'F'}, + {"01OV;N", 'F'}, + {"01OV;T", 'F'}, + {"01OVA(", 'F'}, + {"01OVAF", 'F'}, + {"01OVAS", 'F'}, + {"01OVAT", 'F'}, + {"01OVAV", 'F'}, + {"01OVB(", 'F'}, + {"01OVB1", 'F'}, + {"01OVBE", 'F'}, + {"01OVBF", 'F'}, + {"01OVBN", 'F'}, + {"01OVBS", 'F'}, + {"01OVBV", 'F'}, + {"01OVC", 'F'}, + {"01OVE(", 'F'}, + {"01OVE1", 'F'}, + {"01OVEF", 'F'}, + {"01OVEK", 'F'}, + {"01OVEN", 'F'}, + {"01OVEO", 'F'}, + {"01OVES", 'F'}, + {"01OVEU", 'F'}, + {"01OVEV", 'F'}, + {"01OVF(", 'F'}, + {"01OVK(", 'F'}, + {"01OVK)", 'F'}, + {"01OVK1", 'F'}, + {"01OVKB", 'F'}, + {"01OVKF", 'F'}, + {"01OVKN", 'F'}, + {"01OVKS", 'F'}, + {"01OVKU", 'F'}, + {"01OVKV", 'F'}, + {"01OVO(", 'F'}, + {"01OVOF", 'F'}, + {"01OVOK", 'F'}, + {"01OVOS", 'F'}, + {"01OVOT", 'F'}, + {"01OVOU", 'F'}, + {"01OVS(", 'F'}, + {"01OVS1", 'F'}, + {"01OVSF", 'F'}, + {"01OVSO", 'F'}, + {"01OVSU", 'F'}, + {"01OVSV", 'F'}, + {"01OVU", 'F'}, + {"01OVU(", 'F'}, + {"01OVU1", 'F'}, + {"01OVU;", 'F'}, + {"01OVUC", 'F'}, + {"01OVUE", 'F'}, + {"01OVUF", 'F'}, + {"01OVUK", 'F'}, + {"01OVUN", 'F'}, + {"01OVUO", 'F'}, + {"01OVUS", 'F'}, + {"01OVUT", 'F'}, + {"01OVUV", 'F'}, + {"01SF((", 'F'}, + {"01SF()", 'F'}, + {"01SF(1", 'F'}, + {"01SF(F", 'F'}, + {"01SF(N", 'F'}, + {"01SF(S", 'F'}, + {"01SF(V", 'F'}, + {"01SUE", 'F'}, + {"01SUE;", 'F'}, + {"01SUEC", 'F'}, + {"01SUEK", 'F'}, + {"01SV", 'F'}, + {"01SV;", 'F'}, + {"01SV;C", 'F'}, + {"01SVC", 'F'}, + {"01SVO(", 'F'}, + {"01SVOF", 'F'}, + {"01SVOS", 'F'}, + {"01U", 'F'}, + {"01U(((", 'F'}, + {"01U((1", 'F'}, + {"01U((E", 'F'}, + {"01U((F", 'F'}, + {"01U((N", 'F'}, + {"01U((S", 'F'}, + {"01U((V", 'F'}, + {"01U(1)", 'F'}, + {"01U(1O", 'F'}, + {"01U(E(", 'F'}, + {"01U(E1", 'F'}, + {"01U(EF", 'F'}, + {"01U(EK", 'F'}, + {"01U(EN", 'F'}, + {"01U(ES", 'F'}, + {"01U(EV", 'F'}, + {"01U(F(", 'F'}, + {"01U(N)", 'F'}, + {"01U(NO", 'F'}, + {"01U(S)", 'F'}, + {"01U(SO", 'F'}, + {"01U(V)", 'F'}, + {"01U(VO", 'F'}, + {"01U1,(", 'F'}, + {"01U1,F", 'F'}, + {"01U1,V", 'F'}, + {"01U1C", 'F'}, + {"01U1O(", 'F'}, + {"01U1OF", 'F'}, + {"01U1OS", 'F'}, + {"01U1OV", 'F'}, + {"01U;", 'F'}, + {"01U;C", 'F'}, + {"01UC", 'F'}, + {"01UE", 'F'}, + {"01UE((", 'F'}, + {"01UE(1", 'F'}, + {"01UE(E", 'F'}, + {"01UE(F", 'F'}, + {"01UE(N", 'F'}, + {"01UE(O", 'F'}, + {"01UE(S", 'F'}, + {"01UE(V", 'F'}, + {"01UE1", 'F'}, + {"01UE1&", 'F'}, + {"01UE1(", 'F'}, + {"01UE1)", 'F'}, + {"01UE1,", 'F'}, + {"01UE1;", 'F'}, + {"01UE1B", 'F'}, + {"01UE1C", 'F'}, + {"01UE1F", 'F'}, + {"01UE1K", 'F'}, + {"01UE1N", 'F'}, + {"01UE1O", 'F'}, + {"01UE1S", 'F'}, + {"01UE1U", 'F'}, + {"01UE1V", 'F'}, + {"01UE;", 'F'}, + {"01UE;C", 'F'}, + {"01UEC", 'F'}, + {"01UEF", 'F'}, + {"01UEF(", 'F'}, + {"01UEF,", 'F'}, + {"01UEF;", 'F'}, + {"01UEFC", 'F'}, + {"01UEK", 'F'}, + {"01UEK(", 'F'}, + {"01UEK1", 'F'}, + {"01UEK;", 'F'}, + {"01UEKC", 'F'}, + {"01UEKF", 'F'}, + {"01UEKN", 'F'}, + {"01UEKO", 'F'}, + {"01UEKS", 'F'}, + {"01UEKV", 'F'}, + {"01UEN", 'F'}, + {"01UEN&", 'F'}, + {"01UEN(", 'F'}, + {"01UEN)", 'F'}, + {"01UEN,", 'F'}, + {"01UEN1", 'F'}, + {"01UEN;", 'F'}, + {"01UENB", 'F'}, + {"01UENC", 'F'}, + {"01UENF", 'F'}, + {"01UENK", 'F'}, + {"01UENO", 'F'}, + {"01UENS", 'F'}, + {"01UENU", 'F'}, + {"01UEOK", 'F'}, + {"01UEON", 'F'}, + {"01UEOO", 'F'}, + {"01UES", 'F'}, + {"01UES&", 'F'}, + {"01UES(", 'F'}, + {"01UES)", 'F'}, + {"01UES,", 'F'}, + {"01UES1", 'F'}, + {"01UES;", 'F'}, + {"01UESB", 'F'}, + {"01UESC", 'F'}, + {"01UESF", 'F'}, + {"01UESK", 'F'}, + {"01UESO", 'F'}, + {"01UESU", 'F'}, + {"01UESV", 'F'}, + {"01UEV", 'F'}, + {"01UEV&", 'F'}, + {"01UEV(", 'F'}, + {"01UEV)", 'F'}, + {"01UEV,", 'F'}, + {"01UEV;", 'F'}, + {"01UEVB", 'F'}, + {"01UEVC", 'F'}, + {"01UEVF", 'F'}, + {"01UEVK", 'F'}, + {"01UEVN", 'F'}, + {"01UEVO", 'F'}, + {"01UEVS", 'F'}, + {"01UEVU", 'F'}, + {"01UF((", 'F'}, + {"01UF()", 'F'}, + {"01UF(1", 'F'}, + {"01UF(F", 'F'}, + {"01UF(N", 'F'}, + {"01UF(S", 'F'}, + {"01UF(V", 'F'}, + {"01UK((", 'F'}, + {"01UK(E", 'F'}, + {"01UN((", 'F'}, + {"01UN(1", 'F'}, + {"01UN(F", 'F'}, + {"01UN(S", 'F'}, + {"01UN(V", 'F'}, + {"01UN,(", 'F'}, + {"01UN,F", 'F'}, + {"01UN,V", 'F'}, + {"01UN1(", 'F'}, + {"01UN1,", 'F'}, + {"01UN1O", 'F'}, + {"01UNC", 'F'}, + {"01UNE(", 'F'}, + {"01UNE1", 'F'}, + {"01UNEF", 'F'}, + {"01UNEN", 'F'}, + {"01UNES", 'F'}, + {"01UNEV", 'F'}, + {"01UNF(", 'F'}, + {"01UNO(", 'F'}, + {"01UNOF", 'F'}, + {"01UNOS", 'F'}, + {"01UNOV", 'F'}, + {"01UNS(", 'F'}, + {"01UNS,", 'F'}, + {"01UNSO", 'F'}, + {"01UO((", 'F'}, + {"01UO(E", 'F'}, + {"01UON(", 'F'}, + {"01UON1", 'F'}, + {"01UONF", 'F'}, + {"01UONS", 'F'}, + {"01US,(", 'F'}, + {"01US,F", 'F'}, + {"01US,V", 'F'}, + {"01USC", 'F'}, + {"01USO(", 'F'}, + {"01USO1", 'F'}, + {"01USOF", 'F'}, + {"01USON", 'F'}, + {"01USOS", 'F'}, + {"01USOV", 'F'}, + {"01UTN(", 'F'}, + {"01UTN1", 'F'}, + {"01UTNF", 'F'}, + {"01UTNS", 'F'}, + {"01UV,(", 'F'}, + {"01UV,1", 'F'}, + {"01UV,F", 'F'}, + {"01UV,N", 'F'}, + {"01UV,S", 'F'}, + {"01UV,V", 'F'}, + {"01UVC", 'F'}, + {"01UVO(", 'F'}, + {"01UVOF", 'F'}, + {"01UVOS", 'F'}, + {"01VF((", 'F'}, + {"01VF()", 'F'}, + {"01VF(1", 'F'}, + {"01VF(F", 'F'}, + {"01VF(N", 'F'}, + {"01VF(S", 'F'}, + {"01VF(V", 'F'}, + {"01VO((", 'F'}, + {"01VO(1", 'F'}, + {"01VO(F", 'F'}, + {"01VO(N", 'F'}, + {"01VO(S", 'F'}, + {"01VO(V", 'F'}, + {"01VOF(", 'F'}, + {"01VOS(", 'F'}, + {"01VOS1", 'F'}, + {"01VOSF", 'F'}, + {"01VOSO", 'F'}, + {"01VOSU", 'F'}, + {"01VOSV", 'F'}, + {"01VS", 'F'}, + {"01VS;", 'F'}, + {"01VS;C", 'F'}, + {"01VSC", 'F'}, + {"01VSO(", 'F'}, + {"01VSO1", 'F'}, + {"01VSOF", 'F'}, + {"01VSON", 'F'}, + {"01VSOS", 'F'}, + {"01VSOV", 'F'}, + {"01VUE", 'F'}, + {"01VUE;", 'F'}, + {"01VUEC", 'F'}, + {"01VUEK", 'F'}, + {"0;TKNC", 'F'}, + {"0E((((", 'F'}, + {"0E(((1", 'F'}, + {"0E(((E", 'F'}, + {"0E(((F", 'F'}, + {"0E(((N", 'F'}, + {"0E(((S", 'F'}, + {"0E(((V", 'F'}, + {"0E((1(", 'F'}, + {"0E((1)", 'F'}, + {"0E((1,", 'F'}, + {"0E((1F", 'F'}, + {"0E((1N", 'F'}, + {"0E((1O", 'F'}, + {"0E((1S", 'F'}, + {"0E((1V", 'F'}, + {"0E((E(", 'F'}, + {"0E((E1", 'F'}, + {"0E((EF", 'F'}, + {"0E((EK", 'F'}, + {"0E((EN", 'F'}, + {"0E((ES", 'F'}, + {"0E((EV", 'F'}, + {"0E((F(", 'F'}, + {"0E((N(", 'F'}, + {"0E((N)", 'F'}, + {"0E((N,", 'F'}, + {"0E((N1", 'F'}, + {"0E((NF", 'F'}, + {"0E((NO", 'F'}, + {"0E((S(", 'F'}, + {"0E((S)", 'F'}, + {"0E((S,", 'F'}, + {"0E((S1", 'F'}, + {"0E((SF", 'F'}, + {"0E((SO", 'F'}, + {"0E((SV", 'F'}, + {"0E((V(", 'F'}, + {"0E((V)", 'F'}, + {"0E((V,", 'F'}, + {"0E((VF", 'F'}, + {"0E((VO", 'F'}, + {"0E((VS", 'F'}, + {"0E(1)&", 'F'}, + {"0E(1))", 'F'}, + {"0E(1),", 'F'}, + {"0E(1)1", 'F'}, + {"0E(1)F", 'F'}, + {"0E(1)K", 'F'}, + {"0E(1)N", 'F'}, + {"0E(1)O", 'F'}, + {"0E(1)S", 'F'}, + {"0E(1)U", 'F'}, + {"0E(1)V", 'F'}, + {"0E(1,F", 'F'}, + {"0E(1F(", 'F'}, + {"0E(1N)", 'F'}, + {"0E(1NO", 'F'}, + {"0E(1O(", 'F'}, + {"0E(1OF", 'F'}, + {"0E(1OS", 'F'}, + {"0E(1OV", 'F'}, + {"0E(1S)", 'F'}, + {"0E(1V)", 'F'}, + {"0E(1VO", 'F'}, + {"0E(E((", 'F'}, + {"0E(E(1", 'F'}, + {"0E(E(E", 'F'}, + {"0E(E(F", 'F'}, + {"0E(E(N", 'F'}, + {"0E(E(S", 'F'}, + {"0E(E(V", 'F'}, + {"0E(E1O", 'F'}, + {"0E(EF(", 'F'}, + {"0E(EK(", 'F'}, + {"0E(EK1", 'F'}, + {"0E(EKF", 'F'}, + {"0E(EKN", 'F'}, + {"0E(EKS", 'F'}, + {"0E(EKV", 'F'}, + {"0E(ENO", 'F'}, + {"0E(ESO", 'F'}, + {"0E(EVO", 'F'}, + {"0E(F((", 'F'}, + {"0E(F()", 'F'}, + {"0E(F(1", 'F'}, + {"0E(F(F", 'F'}, + {"0E(F(N", 'F'}, + {"0E(F(S", 'F'}, + {"0E(F(V", 'F'}, + {"0E(N((", 'F'}, + {"0E(N(1", 'F'}, + {"0E(N(F", 'F'}, + {"0E(N(S", 'F'}, + {"0E(N(V", 'F'}, + {"0E(N)&", 'F'}, + {"0E(N))", 'F'}, + {"0E(N),", 'F'}, + {"0E(N)1", 'F'}, + {"0E(N)F", 'F'}, + {"0E(N)K", 'F'}, + {"0E(N)N", 'F'}, + {"0E(N)O", 'F'}, + {"0E(N)S", 'F'}, + {"0E(N)U", 'F'}, + {"0E(N)V", 'F'}, + {"0E(N,F", 'F'}, + {"0E(N1)", 'F'}, + {"0E(N1O", 'F'}, + {"0E(NF(", 'F'}, + {"0E(NO(", 'F'}, + {"0E(NOF", 'F'}, + {"0E(NOS", 'F'}, + {"0E(NOV", 'F'}, + {"0E(S)&", 'F'}, + {"0E(S))", 'F'}, + {"0E(S),", 'F'}, + {"0E(S)1", 'F'}, + {"0E(S)F", 'F'}, + {"0E(S)K", 'F'}, + {"0E(S)N", 'F'}, + {"0E(S)O", 'F'}, + {"0E(S)S", 'F'}, + {"0E(S)U", 'F'}, + {"0E(S)V", 'F'}, + {"0E(S,F", 'F'}, + {"0E(S1)", 'F'}, + {"0E(S1O", 'F'}, + {"0E(SF(", 'F'}, + {"0E(SO(", 'F'}, + {"0E(SO1", 'F'}, + {"0E(SOF", 'F'}, + {"0E(SON", 'F'}, + {"0E(SOS", 'F'}, + {"0E(SOV", 'F'}, + {"0E(SV)", 'F'}, + {"0E(SVO", 'F'}, + {"0E(V)&", 'F'}, + {"0E(V))", 'F'}, + {"0E(V),", 'F'}, + {"0E(V)1", 'F'}, + {"0E(V)F", 'F'}, + {"0E(V)K", 'F'}, + {"0E(V)N", 'F'}, + {"0E(V)O", 'F'}, + {"0E(V)S", 'F'}, + {"0E(V)U", 'F'}, + {"0E(V)V", 'F'}, + {"0E(V,F", 'F'}, + {"0E(VF(", 'F'}, + {"0E(VO(", 'F'}, + {"0E(VOF", 'F'}, + {"0E(VOS", 'F'}, + {"0E(VS)", 'F'}, + {"0E(VSO", 'F'}, + {"0E1&((", 'F'}, + {"0E1&(E", 'F'}, + {"0E1)", 'F'}, + {"0E1))", 'F'}, + {"0E1)))", 'F'}, + {"0E1))1", 'F'}, + {"0E1));", 'F'}, + {"0E1))C", 'F'}, + {"0E1))F", 'F'}, + {"0E1))K", 'F'}, + {"0E1))N", 'F'}, + {"0E1))O", 'F'}, + {"0E1))S", 'F'}, + {"0E1))U", 'F'}, + {"0E1))V", 'F'}, + {"0E1);", 'F'}, + {"0E1);C", 'F'}, + {"0E1)C", 'F'}, + {"0E1)KN", 'F'}, + {"0E1)O(", 'F'}, + {"0E1)O1", 'F'}, + {"0E1)OF", 'F'}, + {"0E1)ON", 'F'}, + {"0E1)OS", 'F'}, + {"0E1)OV", 'F'}, + {"0E1)UE", 'F'}, + {"0E1,((", 'F'}, + {"0E1,(1", 'F'}, + {"0E1,(F", 'F'}, + {"0E1,(N", 'F'}, + {"0E1,(S", 'F'}, + {"0E1,(V", 'F'}, + {"0E1,F(", 'F'}, + {"0E1,V,", 'F'}, + {"0E1,VK", 'F'}, + {"0E1,VO", 'F'}, + {"0E1F((", 'F'}, + {"0E1F()", 'F'}, + {"0E1F(1", 'F'}, + {"0E1F(F", 'F'}, + {"0E1F(N", 'F'}, + {"0E1F(S", 'F'}, + {"0E1F(V", 'F'}, + {"0E1K((", 'F'}, + {"0E1K(1", 'F'}, + {"0E1K(E", 'F'}, + {"0E1K(F", 'F'}, + {"0E1K(N", 'F'}, + {"0E1K(S", 'F'}, + {"0E1K(V", 'F'}, + {"0E1K1)", 'F'}, + {"0E1K1K", 'F'}, + {"0E1K1O", 'F'}, + {"0E1KF(", 'F'}, + {"0E1KN", 'F'}, + {"0E1KN)", 'F'}, + {"0E1KN;", 'F'}, + {"0E1KNC", 'F'}, + {"0E1KNK", 'F'}, + {"0E1KS)", 'F'}, + {"0E1KSK", 'F'}, + {"0E1KSO", 'F'}, + {"0E1KV)", 'F'}, + {"0E1KVK", 'F'}, + {"0E1KVO", 'F'}, + {"0E1N;", 'F'}, + {"0E1N;C", 'F'}, + {"0E1NC", 'F'}, + {"0E1NKN", 'F'}, + {"0E1NO(", 'F'}, + {"0E1NOF", 'F'}, + {"0E1NOS", 'F'}, + {"0E1NOV", 'F'}, + {"0E1O((", 'F'}, + {"0E1O(1", 'F'}, + {"0E1O(E", 'F'}, + {"0E1O(F", 'F'}, + {"0E1O(N", 'F'}, + {"0E1O(S", 'F'}, + {"0E1O(V", 'F'}, + {"0E1OF(", 'F'}, + {"0E1OS&", 'F'}, + {"0E1OS(", 'F'}, + {"0E1OS)", 'F'}, + {"0E1OS,", 'F'}, + {"0E1OS1", 'F'}, + {"0E1OSF", 'F'}, + {"0E1OSK", 'F'}, + {"0E1OSO", 'F'}, + {"0E1OSV", 'F'}, + {"0E1OV&", 'F'}, + {"0E1OV(", 'F'}, + {"0E1OV)", 'F'}, + {"0E1OV,", 'F'}, + {"0E1OVF", 'F'}, + {"0E1OVK", 'F'}, + {"0E1OVO", 'F'}, + {"0E1OVS", 'F'}, + {"0E1S;", 'F'}, + {"0E1S;C", 'F'}, + {"0E1SC", 'F'}, + {"0E1V", 'F'}, + {"0E1V;", 'F'}, + {"0E1V;C", 'F'}, + {"0E1VC", 'F'}, + {"0E1VO(", 'F'}, + {"0E1VOF", 'F'}, + {"0E1VOS", 'F'}, + {"0ECHO", 'F'}, + {"0ECHO;", 'F'}, + {"0ECHOC", 'F'}, + {"0EE(((", 'F'}, + {"0EE((F", 'F'}, + {"0EE(F(", 'F'}, + {"0EEK((", 'F'}, + {"0EEK(F", 'F'}, + {"0EF(((", 'F'}, + {"0EF(()", 'F'}, + {"0EF((1", 'F'}, + {"0EF((F", 'F'}, + {"0EF((N", 'F'}, + {"0EF((O", 'F'}, + {"0EF((S", 'F'}, + {"0EF((V", 'F'}, + {"0EF()&", 'F'}, + {"0EF())", 'F'}, + {"0EF(),", 'F'}, + {"0EF()1", 'F'}, + {"0EF()F", 'F'}, + {"0EF()K", 'F'}, + {"0EF()N", 'F'}, + {"0EF()O", 'F'}, + {"0EF()S", 'F'}, + {"0EF()V", 'F'}, + {"0EF(1)", 'F'}, + {"0EF(1,", 'F'}, + {"0EF(1O", 'F'}, + {"0EF(F(", 'F'}, + {"0EF(N)", 'F'}, + {"0EF(N,", 'F'}, + {"0EF(NO", 'F'}, + {"0EF(O)", 'F'}, + {"0EF(S)", 'F'}, + {"0EF(S,", 'F'}, + {"0EF(SO", 'F'}, + {"0EF(V)", 'F'}, + {"0EF(V,", 'F'}, + {"0EF(VO", 'F'}, + {"0EK(((", 'F'}, + {"0EK((1", 'F'}, + {"0EK((E", 'F'}, + {"0EK((F", 'F'}, + {"0EK((N", 'F'}, + {"0EK((S", 'F'}, + {"0EK((V", 'F'}, + {"0EK(1(", 'F'}, + {"0EK(1)", 'F'}, + {"0EK(1,", 'F'}, + {"0EK(1F", 'F'}, + {"0EK(1N", 'F'}, + {"0EK(1O", 'F'}, + {"0EK(1S", 'F'}, + {"0EK(1V", 'F'}, + {"0EK(E(", 'F'}, + {"0EK(E1", 'F'}, + {"0EK(EF", 'F'}, + {"0EK(EK", 'F'}, + {"0EK(EN", 'F'}, + {"0EK(ES", 'F'}, + {"0EK(EV", 'F'}, + {"0EK(F(", 'F'}, + {"0EK(N(", 'F'}, + {"0EK(N)", 'F'}, + {"0EK(N,", 'F'}, + {"0EK(N1", 'F'}, + {"0EK(NF", 'F'}, + {"0EK(NO", 'F'}, + {"0EK(S(", 'F'}, + {"0EK(S)", 'F'}, + {"0EK(S,", 'F'}, + {"0EK(S1", 'F'}, + {"0EK(SF", 'F'}, + {"0EK(SO", 'F'}, + {"0EK(SV", 'F'}, + {"0EK(V(", 'F'}, + {"0EK(V)", 'F'}, + {"0EK(V,", 'F'}, + {"0EK(VF", 'F'}, + {"0EK(VO", 'F'}, + {"0EK(VS", 'F'}, + {"0EK1&(", 'F'}, + {"0EK1)", 'F'}, + {"0EK1))", 'F'}, + {"0EK1);", 'F'}, + {"0EK1)C", 'F'}, + {"0EK1)K", 'F'}, + {"0EK1)O", 'F'}, + {"0EK1)U", 'F'}, + {"0EK1,(", 'F'}, + {"0EK1,F", 'F'}, + {"0EK1,V", 'F'}, + {"0EK1F(", 'F'}, + {"0EK1K(", 'F'}, + {"0EK1K1", 'F'}, + {"0EK1KF", 'F'}, + {"0EK1KN", 'F'}, + {"0EK1KS", 'F'}, + {"0EK1KV", 'F'}, + {"0EK1N", 'F'}, + {"0EK1N;", 'F'}, + {"0EK1NC", 'F'}, + {"0EK1NF", 'F'}, + {"0EK1NK", 'F'}, + {"0EK1NO", 'F'}, + {"0EK1O(", 'F'}, + {"0EK1OF", 'F'}, + {"0EK1OS", 'F'}, + {"0EK1OV", 'F'}, + {"0EK1S", 'F'}, + {"0EK1S;", 'F'}, + {"0EK1SC", 'F'}, + {"0EK1SF", 'F'}, + {"0EK1SK", 'F'}, + {"0EK1V", 'F'}, + {"0EK1V;", 'F'}, + {"0EK1VC", 'F'}, + {"0EK1VF", 'F'}, + {"0EK1VK", 'F'}, + {"0EK1VO", 'F'}, + {"0EKE((", 'F'}, + {"0EKE(F", 'F'}, + {"0EKEK(", 'F'}, + {"0EKF((", 'F'}, + {"0EKF()", 'F'}, + {"0EKF(1", 'F'}, + {"0EKF(F", 'F'}, + {"0EKF(N", 'F'}, + {"0EKF(O", 'F'}, + {"0EKF(S", 'F'}, + {"0EKF(V", 'F'}, + {"0EKN&(", 'F'}, + {"0EKN((", 'F'}, + {"0EKN(1", 'F'}, + {"0EKN(F", 'F'}, + {"0EKN(S", 'F'}, + {"0EKN(V", 'F'}, + {"0EKN)", 'F'}, + {"0EKN))", 'F'}, + {"0EKN);", 'F'}, + {"0EKN)C", 'F'}, + {"0EKN)K", 'F'}, + {"0EKN)O", 'F'}, + {"0EKN)U", 'F'}, + {"0EKN,(", 'F'}, + {"0EKN,F", 'F'}, + {"0EKN,V", 'F'}, + {"0EKN1", 'F'}, + {"0EKN1;", 'F'}, + {"0EKN1C", 'F'}, + {"0EKN1F", 'F'}, + {"0EKN1K", 'F'}, + {"0EKN1O", 'F'}, + {"0EKNF(", 'F'}, + {"0EKNK(", 'F'}, + {"0EKNK1", 'F'}, + {"0EKNKF", 'F'}, + {"0EKNKN", 'F'}, + {"0EKNKS", 'F'}, + {"0EKNKV", 'F'}, + {"0EKO((", 'F'}, + {"0EKO(1", 'F'}, + {"0EKO(F", 'F'}, + {"0EKO(N", 'F'}, + {"0EKO(S", 'F'}, + {"0EKO(V", 'F'}, + {"0EKOK(", 'F'}, + {"0EKS&(", 'F'}, + {"0EKS)", 'F'}, + {"0EKS))", 'F'}, + {"0EKS);", 'F'}, + {"0EKS)C", 'F'}, + {"0EKS)K", 'F'}, + {"0EKS)O", 'F'}, + {"0EKS)U", 'F'}, + {"0EKS,(", 'F'}, + {"0EKS,F", 'F'}, + {"0EKS,V", 'F'}, + {"0EKS1", 'F'}, + {"0EKS1;", 'F'}, + {"0EKS1C", 'F'}, + {"0EKS1F", 'F'}, + {"0EKS1K", 'F'}, + {"0EKS1O", 'F'}, + {"0EKSF(", 'F'}, + {"0EKSK(", 'F'}, + {"0EKSK1", 'F'}, + {"0EKSKF", 'F'}, + {"0EKSKN", 'F'}, + {"0EKSKS", 'F'}, + {"0EKSKV", 'F'}, + {"0EKSO(", 'F'}, + {"0EKSO1", 'F'}, + {"0EKSOF", 'F'}, + {"0EKSON", 'F'}, + {"0EKSOS", 'F'}, + {"0EKSOV", 'F'}, + {"0EKSV", 'F'}, + {"0EKSV;", 'F'}, + {"0EKSVC", 'F'}, + {"0EKSVF", 'F'}, + {"0EKSVK", 'F'}, + {"0EKSVO", 'F'}, + {"0EKV&(", 'F'}, + {"0EKV)", 'F'}, + {"0EKV))", 'F'}, + {"0EKV);", 'F'}, + {"0EKV)C", 'F'}, + {"0EKV)K", 'F'}, + {"0EKV)O", 'F'}, + {"0EKV)U", 'F'}, + {"0EKV,(", 'F'}, + {"0EKV,1", 'F'}, + {"0EKV,F", 'F'}, + {"0EKV,N", 'F'}, + {"0EKV,S", 'F'}, + {"0EKV,V", 'F'}, + {"0EKVF(", 'F'}, + {"0EKVK(", 'F'}, + {"0EKVK1", 'F'}, + {"0EKVKF", 'F'}, + {"0EKVKN", 'F'}, + {"0EKVKS", 'F'}, + {"0EKVKV", 'F'}, + {"0EKVO(", 'F'}, + {"0EKVOF", 'F'}, + {"0EKVOS", 'F'}, + {"0EKVS", 'F'}, + {"0EKVS;", 'F'}, + {"0EKVSC", 'F'}, + {"0EKVSF", 'F'}, + {"0EKVSK", 'F'}, + {"0EKVSO", 'F'}, + {"0EN&((", 'F'}, + {"0EN&(E", 'F'}, + {"0EN(((", 'F'}, + {"0EN((1", 'F'}, + {"0EN((F", 'F'}, + {"0EN((N", 'F'}, + {"0EN((S", 'F'}, + {"0EN((V", 'F'}, + {"0EN(1O", 'F'}, + {"0EN(F(", 'F'}, + {"0EN(S)", 'F'}, + {"0EN(SO", 'F'}, + {"0EN(V)", 'F'}, + {"0EN(VO", 'F'}, + {"0EN)", 'F'}, + {"0EN))", 'F'}, + {"0EN)))", 'F'}, + {"0EN))1", 'F'}, + {"0EN));", 'F'}, + {"0EN))C", 'F'}, + {"0EN))F", 'F'}, + {"0EN))K", 'F'}, + {"0EN))N", 'F'}, + {"0EN))O", 'F'}, + {"0EN))S", 'F'}, + {"0EN))U", 'F'}, + {"0EN))V", 'F'}, + {"0EN);", 'F'}, + {"0EN);C", 'F'}, + {"0EN)C", 'F'}, + {"0EN)KN", 'F'}, + {"0EN)O(", 'F'}, + {"0EN)O1", 'F'}, + {"0EN)OF", 'F'}, + {"0EN)ON", 'F'}, + {"0EN)OS", 'F'}, + {"0EN)OV", 'F'}, + {"0EN)UE", 'F'}, + {"0EN,((", 'F'}, + {"0EN,(1", 'F'}, + {"0EN,(F", 'F'}, + {"0EN,(N", 'F'}, + {"0EN,(S", 'F'}, + {"0EN,(V", 'F'}, + {"0EN,F(", 'F'}, + {"0EN,V,", 'F'}, + {"0EN,VK", 'F'}, + {"0EN,VO", 'F'}, + {"0EN1;", 'F'}, + {"0EN1;C", 'F'}, + {"0EN1C", 'F'}, + {"0EN1O(", 'F'}, + {"0EN1OF", 'F'}, + {"0EN1OS", 'F'}, + {"0EN1OV", 'F'}, + {"0ENF((", 'F'}, + {"0ENF()", 'F'}, + {"0ENF(1", 'F'}, + {"0ENF(F", 'F'}, + {"0ENF(N", 'F'}, + {"0ENF(S", 'F'}, + {"0ENF(V", 'F'}, + {"0ENK((", 'F'}, + {"0ENK(1", 'F'}, + {"0ENK(E", 'F'}, + {"0ENK(F", 'F'}, + {"0ENK(N", 'F'}, + {"0ENK(S", 'F'}, + {"0ENK(V", 'F'}, + {"0ENK1)", 'F'}, + {"0ENK1K", 'F'}, + {"0ENK1O", 'F'}, + {"0ENKF(", 'F'}, + {"0ENKN)", 'F'}, + {"0ENKN,", 'F'}, + {"0ENKN;", 'F'}, + {"0ENKNB", 'F'}, + {"0ENKNC", 'F'}, + {"0ENKNK", 'F'}, + {"0ENKS)", 'F'}, + {"0ENKSK", 'F'}, + {"0ENKSO", 'F'}, + {"0ENKV)", 'F'}, + {"0ENKVK", 'F'}, + {"0ENKVO", 'F'}, + {"0ENO((", 'F'}, + {"0ENO(1", 'F'}, + {"0ENO(E", 'F'}, + {"0ENO(F", 'F'}, + {"0ENO(N", 'F'}, + {"0ENO(S", 'F'}, + {"0ENO(V", 'F'}, + {"0ENOF(", 'F'}, + {"0ENOS&", 'F'}, + {"0ENOS(", 'F'}, + {"0ENOS)", 'F'}, + {"0ENOS,", 'F'}, + {"0ENOS1", 'F'}, + {"0ENOSF", 'F'}, + {"0ENOSK", 'F'}, + {"0ENOSO", 'F'}, + {"0ENOSV", 'F'}, + {"0ENOV&", 'F'}, + {"0ENOV(", 'F'}, + {"0ENOV)", 'F'}, + {"0ENOV,", 'F'}, + {"0ENOVF", 'F'}, + {"0ENOVK", 'F'}, + {"0ENOVO", 'F'}, + {"0ENOVS", 'F'}, + {"0EO(((", 'F'}, + {"0EO((1", 'F'}, + {"0EO((F", 'F'}, + {"0EO((N", 'F'}, + {"0EO((S", 'F'}, + {"0EO((V", 'F'}, + {"0EO(1,", 'F'}, + {"0EO(1O", 'F'}, + {"0EO(F(", 'F'}, + {"0EO(N,", 'F'}, + {"0EO(NO", 'F'}, + {"0EO(S,", 'F'}, + {"0EO(SO", 'F'}, + {"0EO(V,", 'F'}, + {"0EO(VO", 'F'}, + {"0EOK((", 'F'}, + {"0EOK(E", 'F'}, + {"0ES&((", 'F'}, + {"0ES&(E", 'F'}, + {"0ES)", 'F'}, + {"0ES))", 'F'}, + {"0ES)))", 'F'}, + {"0ES))1", 'F'}, + {"0ES));", 'F'}, + {"0ES))C", 'F'}, + {"0ES))F", 'F'}, + {"0ES))K", 'F'}, + {"0ES))N", 'F'}, + {"0ES))O", 'F'}, + {"0ES))S", 'F'}, + {"0ES))U", 'F'}, + {"0ES))V", 'F'}, + {"0ES);", 'F'}, + {"0ES);C", 'F'}, + {"0ES)C", 'F'}, + {"0ES)KN", 'F'}, + {"0ES)O(", 'F'}, + {"0ES)O1", 'F'}, + {"0ES)OF", 'F'}, + {"0ES)ON", 'F'}, + {"0ES)OS", 'F'}, + {"0ES)OV", 'F'}, + {"0ES)UE", 'F'}, + {"0ES,((", 'F'}, + {"0ES,(1", 'F'}, + {"0ES,(F", 'F'}, + {"0ES,(N", 'F'}, + {"0ES,(S", 'F'}, + {"0ES,(V", 'F'}, + {"0ES,F(", 'F'}, + {"0ES,V,", 'F'}, + {"0ES,VK", 'F'}, + {"0ES,VO", 'F'}, + {"0ES1", 'F'}, + {"0ES1;", 'F'}, + {"0ES1;C", 'F'}, + {"0ES1C", 'F'}, + {"0ES1O(", 'F'}, + {"0ES1OF", 'F'}, + {"0ES1OS", 'F'}, + {"0ES1OV", 'F'}, + {"0ESF((", 'F'}, + {"0ESF()", 'F'}, + {"0ESF(1", 'F'}, + {"0ESF(F", 'F'}, + {"0ESF(N", 'F'}, + {"0ESF(S", 'F'}, + {"0ESF(V", 'F'}, + {"0ESK((", 'F'}, + {"0ESK(1", 'F'}, + {"0ESK(E", 'F'}, + {"0ESK(F", 'F'}, + {"0ESK(N", 'F'}, + {"0ESK(S", 'F'}, + {"0ESK(V", 'F'}, + {"0ESK1)", 'F'}, + {"0ESK1K", 'F'}, + {"0ESK1O", 'F'}, + {"0ESKF(", 'F'}, + {"0ESKN", 'F'}, + {"0ESKN)", 'F'}, + {"0ESKN;", 'F'}, + {"0ESKNC", 'F'}, + {"0ESKNK", 'F'}, + {"0ESKS)", 'F'}, + {"0ESKSK", 'F'}, + {"0ESKSO", 'F'}, + {"0ESKV)", 'F'}, + {"0ESKVK", 'F'}, + {"0ESKVO", 'F'}, + {"0ESO((", 'F'}, + {"0ESO(1", 'F'}, + {"0ESO(E", 'F'}, + {"0ESO(F", 'F'}, + {"0ESO(N", 'F'}, + {"0ESO(S", 'F'}, + {"0ESO(V", 'F'}, + {"0ESO1&", 'F'}, + {"0ESO1(", 'F'}, + {"0ESO1)", 'F'}, + {"0ESO1,", 'F'}, + {"0ESO1F", 'F'}, + {"0ESO1K", 'F'}, + {"0ESO1N", 'F'}, + {"0ESO1O", 'F'}, + {"0ESO1S", 'F'}, + {"0ESO1V", 'F'}, + {"0ESOF(", 'F'}, + {"0ESON&", 'F'}, + {"0ESON(", 'F'}, + {"0ESON)", 'F'}, + {"0ESON,", 'F'}, + {"0ESON1", 'F'}, + {"0ESONF", 'F'}, + {"0ESONK", 'F'}, + {"0ESONO", 'F'}, + {"0ESOS&", 'F'}, + {"0ESOS(", 'F'}, + {"0ESOS)", 'F'}, + {"0ESOS,", 'F'}, + {"0ESOS1", 'F'}, + {"0ESOSF", 'F'}, + {"0ESOSK", 'F'}, + {"0ESOSO", 'F'}, + {"0ESOSV", 'F'}, + {"0ESOV&", 'F'}, + {"0ESOV(", 'F'}, + {"0ESOV)", 'F'}, + {"0ESOV,", 'F'}, + {"0ESOVF", 'F'}, + {"0ESOVK", 'F'}, + {"0ESOVO", 'F'}, + {"0ESOVS", 'F'}, + {"0ESV", 'F'}, + {"0ESV;", 'F'}, + {"0ESV;C", 'F'}, + {"0ESVC", 'F'}, + {"0ESVO(", 'F'}, + {"0ESVOF", 'F'}, + {"0ESVOS", 'F'}, + {"0EV&((", 'F'}, + {"0EV&(E", 'F'}, + {"0EV)", 'F'}, + {"0EV))", 'F'}, + {"0EV)))", 'F'}, + {"0EV))1", 'F'}, + {"0EV));", 'F'}, + {"0EV))C", 'F'}, + {"0EV))F", 'F'}, + {"0EV))K", 'F'}, + {"0EV))N", 'F'}, + {"0EV))O", 'F'}, + {"0EV))S", 'F'}, + {"0EV))U", 'F'}, + {"0EV))V", 'F'}, + {"0EV);", 'F'}, + {"0EV);C", 'F'}, + {"0EV)C", 'F'}, + {"0EV)KN", 'F'}, + {"0EV)O(", 'F'}, + {"0EV)O1", 'F'}, + {"0EV)OF", 'F'}, + {"0EV)ON", 'F'}, + {"0EV)OS", 'F'}, + {"0EV)OV", 'F'}, + {"0EV)UE", 'F'}, + {"0EV,((", 'F'}, + {"0EV,(1", 'F'}, + {"0EV,(F", 'F'}, + {"0EV,(N", 'F'}, + {"0EV,(S", 'F'}, + {"0EV,(V", 'F'}, + {"0EV,1,", 'F'}, + {"0EV,1K", 'F'}, + {"0EV,1O", 'F'}, + {"0EV,F(", 'F'}, + {"0EV,N,", 'F'}, + {"0EV,NK", 'F'}, + {"0EV,NO", 'F'}, + {"0EV,S,", 'F'}, + {"0EV,SK", 'F'}, + {"0EV,SO", 'F'}, + {"0EV,V,", 'F'}, + {"0EV,VK", 'F'}, + {"0EV,VO", 'F'}, + {"0EVF((", 'F'}, + {"0EVF()", 'F'}, + {"0EVF(1", 'F'}, + {"0EVF(F", 'F'}, + {"0EVF(N", 'F'}, + {"0EVF(S", 'F'}, + {"0EVF(V", 'F'}, + {"0EVK((", 'F'}, + {"0EVK(1", 'F'}, + {"0EVK(E", 'F'}, + {"0EVK(F", 'F'}, + {"0EVK(N", 'F'}, + {"0EVK(S", 'F'}, + {"0EVK(V", 'F'}, + {"0EVK1)", 'F'}, + {"0EVK1K", 'F'}, + {"0EVK1O", 'F'}, + {"0EVKF(", 'F'}, + {"0EVKN", 'F'}, + {"0EVKN)", 'F'}, + {"0EVKN;", 'F'}, + {"0EVKNC", 'F'}, + {"0EVKNK", 'F'}, + {"0EVKS)", 'F'}, + {"0EVKSK", 'F'}, + {"0EVKSO", 'F'}, + {"0EVKV)", 'F'}, + {"0EVKVK", 'F'}, + {"0EVKVO", 'F'}, + {"0EVN", 'F'}, + {"0EVN;", 'F'}, + {"0EVN;C", 'F'}, + {"0EVNC", 'F'}, + {"0EVNKN", 'F'}, + {"0EVNO(", 'F'}, + {"0EVNOF", 'F'}, + {"0EVNOS", 'F'}, + {"0EVNOV", 'F'}, + {"0EVO((", 'F'}, + {"0EVO(1", 'F'}, + {"0EVO(E", 'F'}, + {"0EVO(F", 'F'}, + {"0EVO(N", 'F'}, + {"0EVO(S", 'F'}, + {"0EVO(V", 'F'}, + {"0EVOF(", 'F'}, + {"0EVOS&", 'F'}, + {"0EVOS(", 'F'}, + {"0EVOS)", 'F'}, + {"0EVOS,", 'F'}, + {"0EVOS1", 'F'}, + {"0EVOSF", 'F'}, + {"0EVOSK", 'F'}, + {"0EVOSO", 'F'}, + {"0EVOSV", 'F'}, + {"0EVS", 'F'}, + {"0EVS;", 'F'}, + {"0EVS;C", 'F'}, + {"0EVSC", 'F'}, + {"0EVSO(", 'F'}, + {"0EVSO1", 'F'}, + {"0EVSOF", 'F'}, + {"0EVSON", 'F'}, + {"0EVSOS", 'F'}, + {"0EVSOV", 'F'}, + {"0F((((", 'F'}, + {"0F((()", 'F'}, + {"0F(((1", 'F'}, + {"0F(((E", 'F'}, + {"0F(((F", 'F'}, + {"0F(((K", 'F'}, + {"0F(((N", 'F'}, + {"0F(((S", 'F'}, + {"0F(((T", 'F'}, + {"0F(((V", 'F'}, + {"0F(()&", 'F'}, + {"0F(())", 'F'}, + {"0F((),", 'F'}, + {"0F(()1", 'F'}, + {"0F(();", 'F'}, + {"0F(()A", 'F'}, + {"0F(()B", 'F'}, + {"0F(()C", 'F'}, + {"0F(()E", 'F'}, + {"0F(()F", 'F'}, + {"0F(()K", 'F'}, + {"0F(()N", 'F'}, + {"0F(()O", 'F'}, + {"0F(()S", 'F'}, + {"0F(()U", 'F'}, + {"0F(()V", 'F'}, + {"0F((1)", 'F'}, + {"0F((1,", 'F'}, + {"0F((1O", 'F'}, + {"0F((E(", 'F'}, + {"0F((E1", 'F'}, + {"0F((EF", 'F'}, + {"0F((EK", 'F'}, + {"0F((EN", 'F'}, + {"0F((ES", 'F'}, + {"0F((EV", 'F'}, + {"0F((F(", 'F'}, + {"0F((K(", 'F'}, + {"0F((K,", 'F'}, + {"0F((N)", 'F'}, + {"0F((N,", 'F'}, + {"0F((NO", 'F'}, + {"0F((S)", 'F'}, + {"0F((S,", 'F'}, + {"0F((SO", 'F'}, + {"0F((T)", 'F'}, + {"0F((T,", 'F'}, + {"0F((V)", 'F'}, + {"0F((V,", 'F'}, + {"0F((VO", 'F'}, + {"0F()&(", 'F'}, + {"0F()&1", 'F'}, + {"0F()&E", 'F'}, + {"0F()&F", 'F'}, + {"0F()&K", 'F'}, + {"0F()&N", 'F'}, + {"0F()&S", 'F'}, + {"0F()&V", 'F'}, + {"0F())&", 'F'}, + {"0F()))", 'F'}, + {"0F()),", 'F'}, + {"0F())1", 'F'}, + {"0F());", 'F'}, + {"0F())A", 'F'}, + {"0F())B", 'F'}, + {"0F())C", 'F'}, + {"0F())E", 'F'}, + {"0F())F", 'F'}, + {"0F())K", 'F'}, + {"0F())N", 'F'}, + {"0F())O", 'F'}, + {"0F())S", 'F'}, + {"0F())U", 'F'}, + {"0F())V", 'F'}, + {"0F(),(", 'F'}, + {"0F(),1", 'F'}, + {"0F(),F", 'F'}, + {"0F(),N", 'F'}, + {"0F(),S", 'F'}, + {"0F(),V", 'F'}, + {"0F()1(", 'F'}, + {"0F()1F", 'F'}, + {"0F()1N", 'F'}, + {"0F()1O", 'F'}, + {"0F()1S", 'F'}, + {"0F()1U", 'F'}, + {"0F()1V", 'F'}, + {"0F();E", 'F'}, + {"0F();N", 'F'}, + {"0F();T", 'F'}, + {"0F()A(", 'F'}, + {"0F()AF", 'F'}, + {"0F()AS", 'F'}, + {"0F()AT", 'F'}, + {"0F()AV", 'F'}, + {"0F()B(", 'F'}, + {"0F()B1", 'F'}, + {"0F()BE", 'F'}, + {"0F()BF", 'F'}, + {"0F()BN", 'F'}, + {"0F()BS", 'F'}, + {"0F()BV", 'F'}, + {"0F()C", 'F'}, + {"0F()E(", 'F'}, + {"0F()E1", 'F'}, + {"0F()EF", 'F'}, + {"0F()EK", 'F'}, + {"0F()EN", 'F'}, + {"0F()EO", 'F'}, + {"0F()ES", 'F'}, + {"0F()EU", 'F'}, + {"0F()EV", 'F'}, + {"0F()F(", 'F'}, + {"0F()K(", 'F'}, + {"0F()K)", 'F'}, + {"0F()K1", 'F'}, + {"0F()KF", 'F'}, + {"0F()KN", 'F'}, + {"0F()KS", 'F'}, + {"0F()KU", 'F'}, + {"0F()KV", 'F'}, + {"0F()N&", 'F'}, + {"0F()N(", 'F'}, + {"0F()N)", 'F'}, + {"0F()N,", 'F'}, + {"0F()N1", 'F'}, + {"0F()NE", 'F'}, + {"0F()NF", 'F'}, + {"0F()NO", 'F'}, + {"0F()NU", 'F'}, + {"0F()O(", 'F'}, + {"0F()O1", 'F'}, + {"0F()OF", 'F'}, + {"0F()OK", 'F'}, + {"0F()ON", 'F'}, + {"0F()OS", 'F'}, + {"0F()OT", 'F'}, + {"0F()OU", 'F'}, + {"0F()OV", 'F'}, + {"0F()S(", 'F'}, + {"0F()S1", 'F'}, + {"0F()SF", 'F'}, + {"0F()SO", 'F'}, + {"0F()SU", 'F'}, + {"0F()SV", 'F'}, + {"0F()U", 'F'}, + {"0F()U(", 'F'}, + {"0F()U1", 'F'}, + {"0F()U;", 'F'}, + {"0F()UC", 'F'}, + {"0F()UE", 'F'}, + {"0F()UF", 'F'}, + {"0F()UK", 'F'}, + {"0F()UN", 'F'}, + {"0F()UO", 'F'}, + {"0F()US", 'F'}, + {"0F()UT", 'F'}, + {"0F()UV", 'F'}, + {"0F()V(", 'F'}, + {"0F()VF", 'F'}, + {"0F()VO", 'F'}, + {"0F()VS", 'F'}, + {"0F()VU", 'F'}, + {"0F(1)", 'F'}, + {"0F(1)&", 'F'}, + {"0F(1))", 'F'}, + {"0F(1),", 'F'}, + {"0F(1)1", 'F'}, + {"0F(1);", 'F'}, + {"0F(1)A", 'F'}, + {"0F(1)B", 'F'}, + {"0F(1)C", 'F'}, + {"0F(1)E", 'F'}, + {"0F(1)F", 'F'}, + {"0F(1)K", 'F'}, + {"0F(1)N", 'F'}, + {"0F(1)O", 'F'}, + {"0F(1)S", 'F'}, + {"0F(1)U", 'F'}, + {"0F(1)V", 'F'}, + {"0F(1,(", 'F'}, + {"0F(1,F", 'F'}, + {"0F(1,V", 'F'}, + {"0F(1O(", 'F'}, + {"0F(1OF", 'F'}, + {"0F(1OS", 'F'}, + {"0F(1OV", 'F'}, + {"0F(E((", 'F'}, + {"0F(E(1", 'F'}, + {"0F(E(F", 'F'}, + {"0F(E(N", 'F'}, + {"0F(E(S", 'F'}, + {"0F(E(V", 'F'}, + {"0F(E1O", 'F'}, + {"0F(EF(", 'F'}, + {"0F(EK(", 'F'}, + {"0F(EK1", 'F'}, + {"0F(EKF", 'F'}, + {"0F(EKN", 'F'}, + {"0F(EKS", 'F'}, + {"0F(EKV", 'F'}, + {"0F(ENO", 'F'}, + {"0F(ESO", 'F'}, + {"0F(EVO", 'F'}, + {"0F(F((", 'F'}, + {"0F(F()", 'F'}, + {"0F(F(1", 'F'}, + {"0F(F(F", 'F'}, + {"0F(F(N", 'F'}, + {"0F(F(S", 'F'}, + {"0F(F(V", 'F'}, + {"0F(K((", 'F'}, + {"0F(K()", 'F'}, + {"0F(K,(", 'F'}, + {"0F(K,F", 'F'}, + {"0F(N)", 'F'}, + {"0F(N)&", 'F'}, + {"0F(N))", 'F'}, + {"0F(N),", 'F'}, + {"0F(N)1", 'F'}, + {"0F(N);", 'F'}, + {"0F(N)A", 'F'}, + {"0F(N)B", 'F'}, + {"0F(N)C", 'F'}, + {"0F(N)E", 'F'}, + {"0F(N)F", 'F'}, + {"0F(N)K", 'F'}, + {"0F(N)N", 'F'}, + {"0F(N)O", 'F'}, + {"0F(N)S", 'F'}, + {"0F(N)U", 'F'}, + {"0F(N)V", 'F'}, + {"0F(N,(", 'F'}, + {"0F(N,F", 'F'}, + {"0F(N,V", 'F'}, + {"0F(NO(", 'F'}, + {"0F(NOF", 'F'}, + {"0F(NOS", 'F'}, + {"0F(NOV", 'F'}, + {"0F(S)", 'F'}, + {"0F(S)&", 'F'}, + {"0F(S))", 'F'}, + {"0F(S),", 'F'}, + {"0F(S)1", 'F'}, + {"0F(S);", 'F'}, + {"0F(S)A", 'F'}, + {"0F(S)B", 'F'}, + {"0F(S)C", 'F'}, + {"0F(S)E", 'F'}, + {"0F(S)F", 'F'}, + {"0F(S)K", 'F'}, + {"0F(S)N", 'F'}, + {"0F(S)O", 'F'}, + {"0F(S)S", 'F'}, + {"0F(S)U", 'F'}, + {"0F(S)V", 'F'}, + {"0F(S,(", 'F'}, + {"0F(S,F", 'F'}, + {"0F(S,V", 'F'}, + {"0F(SO(", 'F'}, + {"0F(SO1", 'F'}, + {"0F(SOF", 'F'}, + {"0F(SON", 'F'}, + {"0F(SOS", 'F'}, + {"0F(SOV", 'F'}, + {"0F(T))", 'F'}, + {"0F(T),", 'F'}, + {"0F(T,(", 'F'}, + {"0F(T,1", 'F'}, + {"0F(T,F", 'F'}, + {"0F(T,N", 'F'}, + {"0F(T,S", 'F'}, + {"0F(T,V", 'F'}, + {"0F(V)", 'F'}, + {"0F(V)&", 'F'}, + {"0F(V))", 'F'}, + {"0F(V),", 'F'}, + {"0F(V)1", 'F'}, + {"0F(V);", 'F'}, + {"0F(V)A", 'F'}, + {"0F(V)B", 'F'}, + {"0F(V)C", 'F'}, + {"0F(V)E", 'F'}, + {"0F(V)F", 'F'}, + {"0F(V)K", 'F'}, + {"0F(V)N", 'F'}, + {"0F(V)O", 'F'}, + {"0F(V)S", 'F'}, + {"0F(V)U", 'F'}, + {"0F(V)V", 'F'}, + {"0F(V,(", 'F'}, + {"0F(V,1", 'F'}, + {"0F(V,F", 'F'}, + {"0F(V,N", 'F'}, + {"0F(V,S", 'F'}, + {"0F(V,V", 'F'}, + {"0F(VO(", 'F'}, + {"0F(VOF", 'F'}, + {"0F(VOS", 'F'}, + {"0K((((", 'F'}, + {"0K(((1", 'F'}, + {"0K(((F", 'F'}, + {"0K(((N", 'F'}, + {"0K(((S", 'F'}, + {"0K(((V", 'F'}, + {"0K((1)", 'F'}, + {"0K((1O", 'F'}, + {"0K((F(", 'F'}, + {"0K((N)", 'F'}, + {"0K((NO", 'F'}, + {"0K((S)", 'F'}, + {"0K((SO", 'F'}, + {"0K((V)", 'F'}, + {"0K((VO", 'F'}, + {"0K(1))", 'F'}, + {"0K(1),", 'F'}, + {"0K(1)A", 'F'}, + {"0K(1)K", 'F'}, + {"0K(1)O", 'F'}, + {"0K(1O(", 'F'}, + {"0K(1OF", 'F'}, + {"0K(1OS", 'F'}, + {"0K(1OV", 'F'}, + {"0K(F((", 'F'}, + {"0K(F()", 'F'}, + {"0K(F(1", 'F'}, + {"0K(F(F", 'F'}, + {"0K(F(N", 'F'}, + {"0K(F(S", 'F'}, + {"0K(F(V", 'F'}, + {"0K(N))", 'F'}, + {"0K(N),", 'F'}, + {"0K(N)A", 'F'}, + {"0K(N)K", 'F'}, + {"0K(N)O", 'F'}, + {"0K(NO(", 'F'}, + {"0K(NOF", 'F'}, + {"0K(NOS", 'F'}, + {"0K(NOV", 'F'}, + {"0K(S))", 'F'}, + {"0K(S),", 'F'}, + {"0K(S)A", 'F'}, + {"0K(S)K", 'F'}, + {"0K(S)O", 'F'}, + {"0K(SO(", 'F'}, + {"0K(SO1", 'F'}, + {"0K(SOF", 'F'}, + {"0K(SON", 'F'}, + {"0K(SOS", 'F'}, + {"0K(SOV", 'F'}, + {"0K(V))", 'F'}, + {"0K(V),", 'F'}, + {"0K(V)A", 'F'}, + {"0K(V)K", 'F'}, + {"0K(V)O", 'F'}, + {"0K(VO(", 'F'}, + {"0K(VOF", 'F'}, + {"0K(VOS", 'F'}, + {"0K1,((", 'F'}, + {"0K1,(1", 'F'}, + {"0K1,(F", 'F'}, + {"0K1,(N", 'F'}, + {"0K1,(S", 'F'}, + {"0K1,(V", 'F'}, + {"0K1,F(", 'F'}, + {"0K1,VC", 'F'}, + {"0K1,VO", 'F'}, + {"0K1A((", 'F'}, + {"0K1A(F", 'F'}, + {"0K1A(N", 'F'}, + {"0K1A(S", 'F'}, + {"0K1A(V", 'F'}, + {"0K1AF(", 'F'}, + {"0K1ASO", 'F'}, + {"0K1ATO", 'F'}, + {"0K1AVO", 'F'}, + {"0K1K((", 'F'}, + {"0K1K(1", 'F'}, + {"0K1K(F", 'F'}, + {"0K1K(N", 'F'}, + {"0K1K(S", 'F'}, + {"0K1K(V", 'F'}, + {"0K1K1O", 'F'}, + {"0K1K1U", 'F'}, + {"0K1KF(", 'F'}, + {"0K1KNU", 'F'}, + {"0K1KSO", 'F'}, + {"0K1KSU", 'F'}, + {"0K1KVO", 'F'}, + {"0K1KVU", 'F'}, + {"0K1O((", 'F'}, + {"0K1O(1", 'F'}, + {"0K1O(F", 'F'}, + {"0K1O(N", 'F'}, + {"0K1O(S", 'F'}, + {"0K1O(V", 'F'}, + {"0K1OF(", 'F'}, + {"0K1OS(", 'F'}, + {"0K1OS,", 'F'}, + {"0K1OS1", 'F'}, + {"0K1OSA", 'F'}, + {"0K1OSF", 'F'}, + {"0K1OSK", 'F'}, + {"0K1OSO", 'F'}, + {"0K1OSV", 'F'}, + {"0K1OV(", 'F'}, + {"0K1OV,", 'F'}, + {"0K1OVA", 'F'}, + {"0K1OVF", 'F'}, + {"0K1OVK", 'F'}, + {"0K1OVO", 'F'}, + {"0K1OVS", 'F'}, + {"0KF(((", 'F'}, + {"0KF(()", 'F'}, + {"0KF((1", 'F'}, + {"0KF((F", 'F'}, + {"0KF((N", 'F'}, + {"0KF((S", 'F'}, + {"0KF((V", 'F'}, + {"0KF())", 'F'}, + {"0KF(),", 'F'}, + {"0KF()A", 'F'}, + {"0KF()K", 'F'}, + {"0KF()O", 'F'}, + {"0KF(1)", 'F'}, + {"0KF(1O", 'F'}, + {"0KF(F(", 'F'}, + {"0KF(N)", 'F'}, + {"0KF(NO", 'F'}, + {"0KF(S)", 'F'}, + {"0KF(SO", 'F'}, + {"0KF(V)", 'F'}, + {"0KF(VO", 'F'}, + {"0KN,((", 'F'}, + {"0KN,(1", 'F'}, + {"0KN,(F", 'F'}, + {"0KN,(N", 'F'}, + {"0KN,(S", 'F'}, + {"0KN,(V", 'F'}, + {"0KN,F(", 'F'}, + {"0KN,VC", 'F'}, + {"0KN,VO", 'F'}, + {"0KNA((", 'F'}, + {"0KNA(F", 'F'}, + {"0KNA(N", 'F'}, + {"0KNA(S", 'F'}, + {"0KNA(V", 'F'}, + {"0KNAF(", 'F'}, + {"0KNASO", 'F'}, + {"0KNATO", 'F'}, + {"0KNAVO", 'F'}, + {"0KNK((", 'F'}, + {"0KNK(1", 'F'}, + {"0KNK(F", 'F'}, + {"0KNK(N", 'F'}, + {"0KNK(S", 'F'}, + {"0KNK(V", 'F'}, + {"0KNK1O", 'F'}, + {"0KNK1U", 'F'}, + {"0KNKF(", 'F'}, + {"0KNKNU", 'F'}, + {"0KNKSO", 'F'}, + {"0KNKSU", 'F'}, + {"0KNKVO", 'F'}, + {"0KNKVU", 'F'}, + {"0KS,((", 'F'}, + {"0KS,(1", 'F'}, + {"0KS,(F", 'F'}, + {"0KS,(N", 'F'}, + {"0KS,(S", 'F'}, + {"0KS,(V", 'F'}, + {"0KS,F(", 'F'}, + {"0KS,VC", 'F'}, + {"0KS,VO", 'F'}, + {"0KSA((", 'F'}, + {"0KSA(F", 'F'}, + {"0KSA(N", 'F'}, + {"0KSA(S", 'F'}, + {"0KSA(V", 'F'}, + {"0KSAF(", 'F'}, + {"0KSASO", 'F'}, + {"0KSATO", 'F'}, + {"0KSAVO", 'F'}, + {"0KSK((", 'F'}, + {"0KSK(1", 'F'}, + {"0KSK(F", 'F'}, + {"0KSK(N", 'F'}, + {"0KSK(S", 'F'}, + {"0KSK(V", 'F'}, + {"0KSK1O", 'F'}, + {"0KSK1U", 'F'}, + {"0KSKF(", 'F'}, + {"0KSKNU", 'F'}, + {"0KSKSO", 'F'}, + {"0KSKSU", 'F'}, + {"0KSKVO", 'F'}, + {"0KSKVU", 'F'}, + {"0KSO((", 'F'}, + {"0KSO(1", 'F'}, + {"0KSO(F", 'F'}, + {"0KSO(N", 'F'}, + {"0KSO(S", 'F'}, + {"0KSO(V", 'F'}, + {"0KSO1(", 'F'}, + {"0KSO1,", 'F'}, + {"0KSO1A", 'F'}, + {"0KSO1F", 'F'}, + {"0KSO1K", 'F'}, + {"0KSO1N", 'F'}, + {"0KSO1O", 'F'}, + {"0KSO1S", 'F'}, + {"0KSO1V", 'F'}, + {"0KSOF(", 'F'}, + {"0KSON(", 'F'}, + {"0KSON,", 'F'}, + {"0KSON1", 'F'}, + {"0KSONA", 'F'}, + {"0KSONF", 'F'}, + {"0KSONK", 'F'}, + {"0KSONO", 'F'}, + {"0KSOS(", 'F'}, + {"0KSOS,", 'F'}, + {"0KSOS1", 'F'}, + {"0KSOSA", 'F'}, + {"0KSOSF", 'F'}, + {"0KSOSK", 'F'}, + {"0KSOSO", 'F'}, + {"0KSOSV", 'F'}, + {"0KSOV(", 'F'}, + {"0KSOV,", 'F'}, + {"0KSOVA", 'F'}, + {"0KSOVF", 'F'}, + {"0KSOVK", 'F'}, + {"0KSOVO", 'F'}, + {"0KSOVS", 'F'}, + {"0KV,((", 'F'}, + {"0KV,(1", 'F'}, + {"0KV,(F", 'F'}, + {"0KV,(N", 'F'}, + {"0KV,(S", 'F'}, + {"0KV,(V", 'F'}, + {"0KV,1C", 'F'}, + {"0KV,1O", 'F'}, + {"0KV,F(", 'F'}, + {"0KV,NC", 'F'}, + {"0KV,NO", 'F'}, + {"0KV,SC", 'F'}, + {"0KV,SO", 'F'}, + {"0KV,VC", 'F'}, + {"0KV,VO", 'F'}, + {"0KVA((", 'F'}, + {"0KVA(F", 'F'}, + {"0KVA(N", 'F'}, + {"0KVA(S", 'F'}, + {"0KVA(V", 'F'}, + {"0KVAF(", 'F'}, + {"0KVASO", 'F'}, + {"0KVATO", 'F'}, + {"0KVAVO", 'F'}, + {"0KVK((", 'F'}, + {"0KVK(1", 'F'}, + {"0KVK(F", 'F'}, + {"0KVK(N", 'F'}, + {"0KVK(S", 'F'}, + {"0KVK(V", 'F'}, + {"0KVK1O", 'F'}, + {"0KVK1U", 'F'}, + {"0KVKF(", 'F'}, + {"0KVKNU", 'F'}, + {"0KVKSO", 'F'}, + {"0KVKSU", 'F'}, + {"0KVKVO", 'F'}, + {"0KVKVU", 'F'}, + {"0KVO((", 'F'}, + {"0KVO(1", 'F'}, + {"0KVO(F", 'F'}, + {"0KVO(N", 'F'}, + {"0KVO(S", 'F'}, + {"0KVO(V", 'F'}, + {"0KVOF(", 'F'}, + {"0KVOS(", 'F'}, + {"0KVOS,", 'F'}, + {"0KVOS1", 'F'}, + {"0KVOSA", 'F'}, + {"0KVOSF", 'F'}, + {"0KVOSK", 'F'}, + {"0KVOSO", 'F'}, + {"0KVOSV", 'F'}, + {"0N&(((", 'F'}, + {"0N&((1", 'F'}, + {"0N&((E", 'F'}, + {"0N&((F", 'F'}, + {"0N&((N", 'F'}, + {"0N&((O", 'F'}, + {"0N&((S", 'F'}, + {"0N&((V", 'F'}, + {"0N&(1&", 'F'}, + {"0N&(1)", 'F'}, + {"0N&(1,", 'F'}, + {"0N&(1O", 'F'}, + {"0N&(E(", 'F'}, + {"0N&(E1", 'F'}, + {"0N&(EF", 'F'}, + {"0N&(EK", 'F'}, + {"0N&(EN", 'F'}, + {"0N&(EO", 'F'}, + {"0N&(ES", 'F'}, + {"0N&(EV", 'F'}, + {"0N&(F(", 'F'}, + {"0N&(N&", 'F'}, + {"0N&(N)", 'F'}, + {"0N&(N,", 'F'}, + {"0N&(NO", 'F'}, + {"0N&(O(", 'F'}, + {"0N&(O1", 'F'}, + {"0N&(OF", 'F'}, + {"0N&(ON", 'F'}, + {"0N&(OS", 'F'}, + {"0N&(OV", 'F'}, + {"0N&(S&", 'F'}, + {"0N&(S)", 'F'}, + {"0N&(S,", 'F'}, + {"0N&(SO", 'F'}, + {"0N&(V&", 'F'}, + {"0N&(V)", 'F'}, + {"0N&(V,", 'F'}, + {"0N&(VO", 'F'}, + {"0N&1", 'F'}, + {"0N&1&(", 'F'}, + {"0N&1&1", 'F'}, + {"0N&1&F", 'F'}, + {"0N&1&N", 'F'}, + {"0N&1&S", 'F'}, + {"0N&1&V", 'F'}, + {"0N&1)&", 'F'}, + {"0N&1))", 'F'}, + {"0N&1)U", 'F'}, + {"0N&1;", 'F'}, + {"0N&1;C", 'F'}, + {"0N&1;E", 'F'}, + {"0N&1;T", 'F'}, + {"0N&1B(", 'F'}, + {"0N&1B1", 'F'}, + {"0N&1BF", 'F'}, + {"0N&1BN", 'F'}, + {"0N&1BS", 'F'}, + {"0N&1BV", 'F'}, + {"0N&1C", 'F'}, + {"0N&1EK", 'F'}, + {"0N&1EN", 'F'}, + {"0N&1F(", 'F'}, + {"0N&1K(", 'F'}, + {"0N&1K1", 'F'}, + {"0N&1KF", 'F'}, + {"0N&1KN", 'F'}, + {"0N&1KS", 'F'}, + {"0N&1KV", 'F'}, + {"0N&1O(", 'F'}, + {"0N&1OF", 'F'}, + {"0N&1OO", 'F'}, + {"0N&1OS", 'F'}, + {"0N&1OV", 'F'}, + {"0N&1TN", 'F'}, + {"0N&1U", 'F'}, + {"0N&1U(", 'F'}, + {"0N&1U;", 'F'}, + {"0N&1UC", 'F'}, + {"0N&1UE", 'F'}, + {"0N&E((", 'F'}, + {"0N&E(1", 'F'}, + {"0N&E(F", 'F'}, + {"0N&E(N", 'F'}, + {"0N&E(O", 'F'}, + {"0N&E(S", 'F'}, + {"0N&E(V", 'F'}, + {"0N&E1", 'F'}, + {"0N&E1;", 'F'}, + {"0N&E1C", 'F'}, + {"0N&E1K", 'F'}, + {"0N&E1O", 'F'}, + {"0N&EF(", 'F'}, + {"0N&EK(", 'F'}, + {"0N&EK1", 'F'}, + {"0N&EKF", 'F'}, + {"0N&EKN", 'F'}, + {"0N&EKS", 'F'}, + {"0N&EKV", 'F'}, + {"0N&EN;", 'F'}, + {"0N&ENC", 'F'}, + {"0N&ENK", 'F'}, + {"0N&ENO", 'F'}, + {"0N&ES", 'F'}, + {"0N&ES;", 'F'}, + {"0N&ESC", 'F'}, + {"0N&ESK", 'F'}, + {"0N&ESO", 'F'}, + {"0N&EV", 'F'}, + {"0N&EV;", 'F'}, + {"0N&EVC", 'F'}, + {"0N&EVK", 'F'}, + {"0N&EVO", 'F'}, + {"0N&F((", 'F'}, + {"0N&F()", 'F'}, + {"0N&F(1", 'F'}, + {"0N&F(F", 'F'}, + {"0N&F(N", 'F'}, + {"0N&F(S", 'F'}, + {"0N&F(V", 'F'}, + {"0N&K&(", 'F'}, + {"0N&K&1", 'F'}, + {"0N&K&F", 'F'}, + {"0N&K&N", 'F'}, + {"0N&K&S", 'F'}, + {"0N&K&V", 'F'}, + {"0N&K((", 'F'}, + {"0N&K(1", 'F'}, + {"0N&K(F", 'F'}, + {"0N&K(N", 'F'}, + {"0N&K(S", 'F'}, + {"0N&K(V", 'F'}, + {"0N&K1O", 'F'}, + {"0N&KF(", 'F'}, + {"0N&KNK", 'F'}, + {"0N&KO(", 'F'}, + {"0N&KO1", 'F'}, + {"0N&KOF", 'F'}, + {"0N&KOK", 'F'}, + {"0N&KON", 'F'}, + {"0N&KOS", 'F'}, + {"0N&KOV", 'F'}, + {"0N&KSO", 'F'}, + {"0N&KVO", 'F'}, + {"0N&N&(", 'F'}, + {"0N&N&1", 'F'}, + {"0N&N&F", 'F'}, + {"0N&N&S", 'F'}, + {"0N&N&V", 'F'}, + {"0N&N)&", 'F'}, + {"0N&N))", 'F'}, + {"0N&N)U", 'F'}, + {"0N&N;C", 'F'}, + {"0N&N;E", 'F'}, + {"0N&N;T", 'F'}, + {"0N&NB(", 'F'}, + {"0N&NB1", 'F'}, + {"0N&NBF", 'F'}, + {"0N&NBN", 'F'}, + {"0N&NBS", 'F'}, + {"0N&NBV", 'F'}, + {"0N&NF(", 'F'}, + {"0N&NK(", 'F'}, + {"0N&NK1", 'F'}, + {"0N&NKF", 'F'}, + {"0N&NKS", 'F'}, + {"0N&NKV", 'F'}, + {"0N&NO(", 'F'}, + {"0N&NOF", 'F'}, + {"0N&NOS", 'F'}, + {"0N&NOV", 'F'}, + {"0N&NU", 'F'}, + {"0N&NU(", 'F'}, + {"0N&NU;", 'F'}, + {"0N&NUC", 'F'}, + {"0N&NUE", 'F'}, + {"0N&S&(", 'F'}, + {"0N&S&1", 'F'}, + {"0N&S&F", 'F'}, + {"0N&S&N", 'F'}, + {"0N&S&S", 'F'}, + {"0N&S&V", 'F'}, + {"0N&S)&", 'F'}, + {"0N&S))", 'F'}, + {"0N&S)U", 'F'}, + {"0N&S1", 'F'}, + {"0N&S1;", 'F'}, + {"0N&S1C", 'F'}, + {"0N&S1O", 'F'}, + {"0N&S;", 'F'}, + {"0N&S;C", 'F'}, + {"0N&S;E", 'F'}, + {"0N&S;T", 'F'}, + {"0N&SB(", 'F'}, + {"0N&SB1", 'F'}, + {"0N&SBF", 'F'}, + {"0N&SBN", 'F'}, + {"0N&SBS", 'F'}, + {"0N&SBV", 'F'}, + {"0N&SC", 'F'}, + {"0N&SEK", 'F'}, + {"0N&SEN", 'F'}, + {"0N&SF(", 'F'}, + {"0N&SK(", 'F'}, + {"0N&SK1", 'F'}, + {"0N&SKF", 'F'}, + {"0N&SKN", 'F'}, + {"0N&SKS", 'F'}, + {"0N&SKV", 'F'}, + {"0N&SO(", 'F'}, + {"0N&SO1", 'F'}, + {"0N&SOF", 'F'}, + {"0N&SON", 'F'}, + {"0N&SOO", 'F'}, + {"0N&SOS", 'F'}, + {"0N&SOV", 'F'}, + {"0N&STN", 'F'}, + {"0N&SU", 'F'}, + {"0N&SU(", 'F'}, + {"0N&SU;", 'F'}, + {"0N&SUC", 'F'}, + {"0N&SUE", 'F'}, + {"0N&SV", 'F'}, + {"0N&SV;", 'F'}, + {"0N&SVC", 'F'}, + {"0N&SVO", 'F'}, + {"0N&V", 'F'}, + {"0N&V&(", 'F'}, + {"0N&V&1", 'F'}, + {"0N&V&F", 'F'}, + {"0N&V&N", 'F'}, + {"0N&V&S", 'F'}, + {"0N&V&V", 'F'}, + {"0N&V)&", 'F'}, + {"0N&V))", 'F'}, + {"0N&V)U", 'F'}, + {"0N&V;", 'F'}, + {"0N&V;C", 'F'}, + {"0N&V;E", 'F'}, + {"0N&V;T", 'F'}, + {"0N&VB(", 'F'}, + {"0N&VB1", 'F'}, + {"0N&VBF", 'F'}, + {"0N&VBN", 'F'}, + {"0N&VBS", 'F'}, + {"0N&VBV", 'F'}, + {"0N&VC", 'F'}, + {"0N&VEK", 'F'}, + {"0N&VEN", 'F'}, + {"0N&VF(", 'F'}, + {"0N&VK(", 'F'}, + {"0N&VK1", 'F'}, + {"0N&VKF", 'F'}, + {"0N&VKN", 'F'}, + {"0N&VKS", 'F'}, + {"0N&VKV", 'F'}, + {"0N&VO(", 'F'}, + {"0N&VOF", 'F'}, + {"0N&VOO", 'F'}, + {"0N&VOS", 'F'}, + {"0N&VS", 'F'}, + {"0N&VS;", 'F'}, + {"0N&VSC", 'F'}, + {"0N&VSO", 'F'}, + {"0N&VTN", 'F'}, + {"0N&VU", 'F'}, + {"0N&VU(", 'F'}, + {"0N&VU;", 'F'}, + {"0N&VUC", 'F'}, + {"0N&VUE", 'F'}, + {"0N((((", 'F'}, + {"0N(((1", 'F'}, + {"0N(((E", 'F'}, + {"0N(((F", 'F'}, + {"0N(((N", 'F'}, + {"0N(((S", 'F'}, + {"0N(((U", 'F'}, + {"0N(((V", 'F'}, + {"0N((1)", 'F'}, + {"0N((1O", 'F'}, + {"0N((EK", 'F'}, + {"0N((EN", 'F'}, + {"0N((F(", 'F'}, + {"0N((N)", 'F'}, + {"0N((NO", 'F'}, + {"0N((S)", 'F'}, + {"0N((SO", 'F'}, + {"0N((U(", 'F'}, + {"0N((V)", 'F'}, + {"0N((VO", 'F'}, + {"0N(1))", 'F'}, + {"0N(1)F", 'F'}, + {"0N(1)O", 'F'}, + {"0N(1)U", 'F'}, + {"0N(1)V", 'F'}, + {"0N(1O(", 'F'}, + {"0N(1OF", 'F'}, + {"0N(1OS", 'F'}, + {"0N(1OV", 'F'}, + {"0N(EKN", 'F'}, + {"0N(ENK", 'F'}, + {"0N(F((", 'F'}, + {"0N(F()", 'F'}, + {"0N(F(1", 'F'}, + {"0N(F(F", 'F'}, + {"0N(F(N", 'F'}, + {"0N(F(S", 'F'}, + {"0N(F(V", 'F'}, + {"0N(S))", 'F'}, + {"0N(S)1", 'F'}, + {"0N(S)F", 'F'}, + {"0N(S)N", 'F'}, + {"0N(S)O", 'F'}, + {"0N(S)S", 'F'}, + {"0N(S)U", 'F'}, + {"0N(S)V", 'F'}, + {"0N(SO(", 'F'}, + {"0N(SO1", 'F'}, + {"0N(SOF", 'F'}, + {"0N(SON", 'F'}, + {"0N(SOS", 'F'}, + {"0N(SOV", 'F'}, + {"0N(U((", 'F'}, + {"0N(U(E", 'F'}, + {"0N(V))", 'F'}, + {"0N(V)1", 'F'}, + {"0N(V)F", 'F'}, + {"0N(V)N", 'F'}, + {"0N(V)O", 'F'}, + {"0N(V)S", 'F'}, + {"0N(V)U", 'F'}, + {"0N(V)V", 'F'}, + {"0N(VO(", 'F'}, + {"0N(VOF", 'F'}, + {"0N(VOS", 'F'}, + {"0N)&((", 'F'}, + {"0N)&(1", 'F'}, + {"0N)&(E", 'F'}, + {"0N)&(F", 'F'}, + {"0N)&(N", 'F'}, + {"0N)&(S", 'F'}, + {"0N)&(V", 'F'}, + {"0N)&1", 'F'}, + {"0N)&1&", 'F'}, + {"0N)&1)", 'F'}, + {"0N)&1;", 'F'}, + {"0N)&1B", 'F'}, + {"0N)&1C", 'F'}, + {"0N)&1F", 'F'}, + {"0N)&1O", 'F'}, + {"0N)&1U", 'F'}, + {"0N)&F(", 'F'}, + {"0N)&N", 'F'}, + {"0N)&N&", 'F'}, + {"0N)&N)", 'F'}, + {"0N)&N;", 'F'}, + {"0N)&NB", 'F'}, + {"0N)&NC", 'F'}, + {"0N)&NF", 'F'}, + {"0N)&NO", 'F'}, + {"0N)&NU", 'F'}, + {"0N)&S", 'F'}, + {"0N)&S&", 'F'}, + {"0N)&S)", 'F'}, + {"0N)&S;", 'F'}, + {"0N)&SB", 'F'}, + {"0N)&SC", 'F'}, + {"0N)&SF", 'F'}, + {"0N)&SO", 'F'}, + {"0N)&SU", 'F'}, + {"0N)&V", 'F'}, + {"0N)&V&", 'F'}, + {"0N)&V)", 'F'}, + {"0N)&V;", 'F'}, + {"0N)&VB", 'F'}, + {"0N)&VC", 'F'}, + {"0N)&VF", 'F'}, + {"0N)&VO", 'F'}, + {"0N)&VU", 'F'}, + {"0N))&(", 'F'}, + {"0N))&1", 'F'}, + {"0N))&F", 'F'}, + {"0N))&N", 'F'}, + {"0N))&S", 'F'}, + {"0N))&V", 'F'}, + {"0N)))&", 'F'}, + {"0N))))", 'F'}, + {"0N))),", 'F'}, + {"0N)));", 'F'}, + {"0N)))B", 'F'}, + {"0N)))E", 'F'}, + {"0N)))K", 'F'}, + {"0N)))O", 'F'}, + {"0N)))U", 'F'}, + {"0N)),(", 'F'}, + {"0N));E", 'F'}, + {"0N));T", 'F'}, + {"0N))B(", 'F'}, + {"0N))B1", 'F'}, + {"0N))BF", 'F'}, + {"0N))BN", 'F'}, + {"0N))BS", 'F'}, + {"0N))BV", 'F'}, + {"0N))E(", 'F'}, + {"0N))E1", 'F'}, + {"0N))EF", 'F'}, + {"0N))EK", 'F'}, + {"0N))EN", 'F'}, + {"0N))ES", 'F'}, + {"0N))EV", 'F'}, + {"0N))K(", 'F'}, + {"0N))K1", 'F'}, + {"0N))KB", 'F'}, + {"0N))KF", 'F'}, + {"0N))KN", 'F'}, + {"0N))KS", 'F'}, + {"0N))KU", 'F'}, + {"0N))KV", 'F'}, + {"0N))O(", 'F'}, + {"0N))O1", 'F'}, + {"0N))OF", 'F'}, + {"0N))ON", 'F'}, + {"0N))OS", 'F'}, + {"0N))OV", 'F'}, + {"0N))U(", 'F'}, + {"0N))UE", 'F'}, + {"0N),((", 'F'}, + {"0N),(1", 'F'}, + {"0N),(F", 'F'}, + {"0N),(N", 'F'}, + {"0N),(S", 'F'}, + {"0N),(V", 'F'}, + {"0N);E(", 'F'}, + {"0N);E1", 'F'}, + {"0N);EF", 'F'}, + {"0N);EK", 'F'}, + {"0N);EN", 'F'}, + {"0N);EO", 'F'}, + {"0N);ES", 'F'}, + {"0N);EV", 'F'}, + {"0N);T(", 'F'}, + {"0N);T1", 'F'}, + {"0N);TF", 'F'}, + {"0N);TK", 'F'}, + {"0N);TN", 'F'}, + {"0N);TO", 'F'}, + {"0N);TS", 'F'}, + {"0N);TV", 'F'}, + {"0N)B((", 'F'}, + {"0N)B(1", 'F'}, + {"0N)B(F", 'F'}, + {"0N)B(N", 'F'}, + {"0N)B(S", 'F'}, + {"0N)B(V", 'F'}, + {"0N)B1", 'F'}, + {"0N)B1&", 'F'}, + {"0N)B1;", 'F'}, + {"0N)B1C", 'F'}, + {"0N)B1K", 'F'}, + {"0N)B1N", 'F'}, + {"0N)B1O", 'F'}, + {"0N)B1U", 'F'}, + {"0N)BF(", 'F'}, + {"0N)BN", 'F'}, + {"0N)BN&", 'F'}, + {"0N)BN;", 'F'}, + {"0N)BNC", 'F'}, + {"0N)BNK", 'F'}, + {"0N)BNO", 'F'}, + {"0N)BNU", 'F'}, + {"0N)BS", 'F'}, + {"0N)BS&", 'F'}, + {"0N)BS;", 'F'}, + {"0N)BSC", 'F'}, + {"0N)BSK", 'F'}, + {"0N)BSO", 'F'}, + {"0N)BSU", 'F'}, + {"0N)BV", 'F'}, + {"0N)BV&", 'F'}, + {"0N)BV;", 'F'}, + {"0N)BVC", 'F'}, + {"0N)BVK", 'F'}, + {"0N)BVO", 'F'}, + {"0N)BVU", 'F'}, + {"0N)E((", 'F'}, + {"0N)E(1", 'F'}, + {"0N)E(F", 'F'}, + {"0N)E(N", 'F'}, + {"0N)E(S", 'F'}, + {"0N)E(V", 'F'}, + {"0N)E1C", 'F'}, + {"0N)E1O", 'F'}, + {"0N)EF(", 'F'}, + {"0N)EK(", 'F'}, + {"0N)EK1", 'F'}, + {"0N)EKF", 'F'}, + {"0N)EKN", 'F'}, + {"0N)EKS", 'F'}, + {"0N)EKV", 'F'}, + {"0N)ENC", 'F'}, + {"0N)ENO", 'F'}, + {"0N)ESC", 'F'}, + {"0N)ESO", 'F'}, + {"0N)EVC", 'F'}, + {"0N)EVO", 'F'}, + {"0N)K((", 'F'}, + {"0N)K(1", 'F'}, + {"0N)K(F", 'F'}, + {"0N)K(N", 'F'}, + {"0N)K(S", 'F'}, + {"0N)K(V", 'F'}, + {"0N)K1&", 'F'}, + {"0N)K1;", 'F'}, + {"0N)K1B", 'F'}, + {"0N)K1E", 'F'}, + {"0N)K1O", 'F'}, + {"0N)K1U", 'F'}, + {"0N)KB(", 'F'}, + {"0N)KB1", 'F'}, + {"0N)KBF", 'F'}, + {"0N)KBN", 'F'}, + {"0N)KBS", 'F'}, + {"0N)KBV", 'F'}, + {"0N)KF(", 'F'}, + {"0N)KN&", 'F'}, + {"0N)KN;", 'F'}, + {"0N)KNB", 'F'}, + {"0N)KNE", 'F'}, + {"0N)KNK", 'F'}, + {"0N)KNU", 'F'}, + {"0N)KS&", 'F'}, + {"0N)KS;", 'F'}, + {"0N)KSB", 'F'}, + {"0N)KSE", 'F'}, + {"0N)KSO", 'F'}, + {"0N)KSU", 'F'}, + {"0N)KUE", 'F'}, + {"0N)KV&", 'F'}, + {"0N)KV;", 'F'}, + {"0N)KVB", 'F'}, + {"0N)KVE", 'F'}, + {"0N)KVO", 'F'}, + {"0N)KVU", 'F'}, + {"0N)O((", 'F'}, + {"0N)O(1", 'F'}, + {"0N)O(E", 'F'}, + {"0N)O(F", 'F'}, + {"0N)O(N", 'F'}, + {"0N)O(S", 'F'}, + {"0N)O(V", 'F'}, + {"0N)O1&", 'F'}, + {"0N)O1)", 'F'}, + {"0N)O1;", 'F'}, + {"0N)O1B", 'F'}, + {"0N)O1C", 'F'}, + {"0N)O1K", 'F'}, + {"0N)O1O", 'F'}, + {"0N)O1U", 'F'}, + {"0N)OF(", 'F'}, + {"0N)ON", 'F'}, + {"0N)ON&", 'F'}, + {"0N)ON)", 'F'}, + {"0N)ON;", 'F'}, + {"0N)ONB", 'F'}, + {"0N)ONC", 'F'}, + {"0N)ONK", 'F'}, + {"0N)ONO", 'F'}, + {"0N)ONU", 'F'}, + {"0N)OS", 'F'}, + {"0N)OS&", 'F'}, + {"0N)OS)", 'F'}, + {"0N)OS;", 'F'}, + {"0N)OSB", 'F'}, + {"0N)OSC", 'F'}, + {"0N)OSK", 'F'}, + {"0N)OSO", 'F'}, + {"0N)OSU", 'F'}, + {"0N)OV", 'F'}, + {"0N)OV&", 'F'}, + {"0N)OV)", 'F'}, + {"0N)OV;", 'F'}, + {"0N)OVB", 'F'}, + {"0N)OVC", 'F'}, + {"0N)OVK", 'F'}, + {"0N)OVO", 'F'}, + {"0N)OVU", 'F'}, + {"0N)U((", 'F'}, + {"0N)U(E", 'F'}, + {"0N)UE(", 'F'}, + {"0N)UE1", 'F'}, + {"0N)UEF", 'F'}, + {"0N)UEK", 'F'}, + {"0N)UEN", 'F'}, + {"0N)UES", 'F'}, + {"0N)UEV", 'F'}, + {"0N,(((", 'F'}, + {"0N,((1", 'F'}, + {"0N,((E", 'F'}, + {"0N,((F", 'F'}, + {"0N,((N", 'F'}, + {"0N,((S", 'F'}, + {"0N,((V", 'F'}, + {"0N,(1)", 'F'}, + {"0N,(1O", 'F'}, + {"0N,(E(", 'F'}, + {"0N,(E1", 'F'}, + {"0N,(EF", 'F'}, + {"0N,(EK", 'F'}, + {"0N,(EN", 'F'}, + {"0N,(ES", 'F'}, + {"0N,(EV", 'F'}, + {"0N,(F(", 'F'}, + {"0N,(NO", 'F'}, + {"0N,(S)", 'F'}, + {"0N,(SO", 'F'}, + {"0N,(V)", 'F'}, + {"0N,(VO", 'F'}, + {"0N,F((", 'F'}, + {"0N,F()", 'F'}, + {"0N,F(1", 'F'}, + {"0N,F(F", 'F'}, + {"0N,F(N", 'F'}, + {"0N,F(S", 'F'}, + {"0N,F(T", 'F'}, + {"0N,F(V", 'F'}, + {"0N,V))", 'F'}, + {"0N,V),", 'F'}, + {"0N,V)O", 'F'}, + {"0N,V,(", 'F'}, + {"0N,V,1", 'F'}, + {"0N,V,F", 'F'}, + {"0N,V,N", 'F'}, + {"0N,V,S", 'F'}, + {"0N,V,V", 'F'}, + {"0N,VB(", 'F'}, + {"0N,VB1", 'F'}, + {"0N,VBF", 'F'}, + {"0N,VBN", 'F'}, + {"0N,VBS", 'F'}, + {"0N,VBV", 'F'}, + {"0N,VO(", 'F'}, + {"0N,VOF", 'F'}, + {"0N,VOS", 'F'}, + {"0N,VUE", 'F'}, + {"0N1F((", 'F'}, + {"0N1F()", 'F'}, + {"0N1F(1", 'F'}, + {"0N1F(F", 'F'}, + {"0N1F(N", 'F'}, + {"0N1F(S", 'F'}, + {"0N1F(V", 'F'}, + {"0N1O((", 'F'}, + {"0N1O(1", 'F'}, + {"0N1O(F", 'F'}, + {"0N1O(N", 'F'}, + {"0N1O(S", 'F'}, + {"0N1O(V", 'F'}, + {"0N1OF(", 'F'}, + {"0N1OS(", 'F'}, + {"0N1OS1", 'F'}, + {"0N1OSF", 'F'}, + {"0N1OSO", 'F'}, + {"0N1OSU", 'F'}, + {"0N1OSV", 'F'}, + {"0N1OV(", 'F'}, + {"0N1OVF", 'F'}, + {"0N1OVO", 'F'}, + {"0N1OVS", 'F'}, + {"0N1OVU", 'F'}, + {"0N1S;", 'F'}, + {"0N1S;C", 'F'}, + {"0N1SC", 'F'}, + {"0N1UE", 'F'}, + {"0N1UE;", 'F'}, + {"0N1UEC", 'F'}, + {"0N1UEK", 'F'}, + {"0N1V;", 'F'}, + {"0N1V;C", 'F'}, + {"0N1VC", 'F'}, + {"0N1VO(", 'F'}, + {"0N1VOF", 'F'}, + {"0N1VOS", 'F'}, + {"0N;E((", 'F'}, + {"0N;E(1", 'F'}, + {"0N;E(E", 'F'}, + {"0N;E(F", 'F'}, + {"0N;E(N", 'F'}, + {"0N;E(S", 'F'}, + {"0N;E(V", 'F'}, + {"0N;E1,", 'F'}, + {"0N;E1;", 'F'}, + {"0N;E1C", 'F'}, + {"0N;E1O", 'F'}, + {"0N;E1T", 'F'}, + {"0N;EF(", 'F'}, + {"0N;EK(", 'F'}, + {"0N;EK1", 'F'}, + {"0N;EKF", 'F'}, + {"0N;EKN", 'F'}, + {"0N;EKO", 'F'}, + {"0N;EKS", 'F'}, + {"0N;EKV", 'F'}, + {"0N;EN,", 'F'}, + {"0N;EN;", 'F'}, + {"0N;ENC", 'F'}, + {"0N;ENK", 'F'}, + {"0N;ENO", 'F'}, + {"0N;ENT", 'F'}, + {"0N;EO(", 'F'}, + {"0N;ES,", 'F'}, + {"0N;ES;", 'F'}, + {"0N;ESC", 'F'}, + {"0N;ESO", 'F'}, + {"0N;EST", 'F'}, + {"0N;EV,", 'F'}, + {"0N;EV;", 'F'}, + {"0N;EVC", 'F'}, + {"0N;EVO", 'F'}, + {"0N;EVT", 'F'}, + {"0N;N:T", 'F'}, + {"0N;T((", 'F'}, + {"0N;T(1", 'F'}, + {"0N;T(E", 'F'}, + {"0N;T(F", 'F'}, + {"0N;T(N", 'F'}, + {"0N;T(S", 'F'}, + {"0N;T(V", 'F'}, + {"0N;T1,", 'F'}, + {"0N;T1;", 'F'}, + {"0N;T1C", 'F'}, + {"0N;T1F", 'F'}, + {"0N;T1O", 'F'}, + {"0N;T1T", 'F'}, + {"0N;T;", 'F'}, + {"0N;T;C", 'F'}, + {"0N;TF(", 'F'}, + {"0N;TK(", 'F'}, + {"0N;TK1", 'F'}, + {"0N;TKF", 'F'}, + {"0N;TKK", 'F'}, + {"0N;TKN", 'F'}, + {"0N;TKO", 'F'}, + {"0N;TKS", 'F'}, + {"0N;TKV", 'F'}, + {"0N;TN(", 'F'}, + {"0N;TN,", 'F'}, + {"0N;TN1", 'F'}, + {"0N;TN;", 'F'}, + {"0N;TNC", 'F'}, + {"0N;TNE", 'F'}, + {"0N;TNF", 'F'}, + {"0N;TNK", 'F'}, + {"0N;TNN", 'F'}, + {"0N;TNO", 'F'}, + {"0N;TNS", 'F'}, + {"0N;TNT", 'F'}, + {"0N;TNV", 'F'}, + {"0N;TO(", 'F'}, + {"0N;TS,", 'F'}, + {"0N;TS;", 'F'}, + {"0N;TSC", 'F'}, + {"0N;TSF", 'F'}, + {"0N;TSO", 'F'}, + {"0N;TST", 'F'}, + {"0N;TT(", 'F'}, + {"0N;TT1", 'F'}, + {"0N;TTF", 'F'}, + {"0N;TTN", 'F'}, + {"0N;TTS", 'F'}, + {"0N;TTV", 'F'}, + {"0N;TV,", 'F'}, + {"0N;TV;", 'F'}, + {"0N;TVC", 'F'}, + {"0N;TVF", 'F'}, + {"0N;TVO", 'F'}, + {"0N;TVT", 'F'}, + {"0NA(((", 'F'}, + {"0NA((1", 'F'}, + {"0NA((F", 'F'}, + {"0NA((N", 'F'}, + {"0NA((S", 'F'}, + {"0NA((V", 'F'}, + {"0NA(F(", 'F'}, + {"0NA(N)", 'F'}, + {"0NA(NO", 'F'}, + {"0NA(S)", 'F'}, + {"0NA(SO", 'F'}, + {"0NA(V)", 'F'}, + {"0NA(VO", 'F'}, + {"0NAF((", 'F'}, + {"0NAF()", 'F'}, + {"0NAF(1", 'F'}, + {"0NAF(F", 'F'}, + {"0NAF(N", 'F'}, + {"0NAF(S", 'F'}, + {"0NAF(V", 'F'}, + {"0NASO(", 'F'}, + {"0NASO1", 'F'}, + {"0NASOF", 'F'}, + {"0NASON", 'F'}, + {"0NASOS", 'F'}, + {"0NASOV", 'F'}, + {"0NASUE", 'F'}, + {"0NATO(", 'F'}, + {"0NATO1", 'F'}, + {"0NATOF", 'F'}, + {"0NATON", 'F'}, + {"0NATOS", 'F'}, + {"0NATOV", 'F'}, + {"0NATUE", 'F'}, + {"0NAVO(", 'F'}, + {"0NAVOF", 'F'}, + {"0NAVOS", 'F'}, + {"0NAVUE", 'F'}, + {"0NB(((", 'F'}, + {"0NB((1", 'F'}, + {"0NB((F", 'F'}, + {"0NB((N", 'F'}, + {"0NB((S", 'F'}, + {"0NB((V", 'F'}, + {"0NB(1)", 'F'}, + {"0NB(1O", 'F'}, + {"0NB(F(", 'F'}, + {"0NB(N)", 'F'}, + {"0NB(NO", 'F'}, + {"0NB(S)", 'F'}, + {"0NB(SO", 'F'}, + {"0NB(V)", 'F'}, + {"0NB(VO", 'F'}, + {"0NB1", 'F'}, + {"0NB1&(", 'F'}, + {"0NB1&1", 'F'}, + {"0NB1&F", 'F'}, + {"0NB1&N", 'F'}, + {"0NB1&S", 'F'}, + {"0NB1&V", 'F'}, + {"0NB1,(", 'F'}, + {"0NB1,F", 'F'}, + {"0NB1,V", 'F'}, + {"0NB1;", 'F'}, + {"0NB1;C", 'F'}, + {"0NB1B(", 'F'}, + {"0NB1B1", 'F'}, + {"0NB1BF", 'F'}, + {"0NB1BN", 'F'}, + {"0NB1BS", 'F'}, + {"0NB1BV", 'F'}, + {"0NB1C", 'F'}, + {"0NB1K(", 'F'}, + {"0NB1K1", 'F'}, + {"0NB1KF", 'F'}, + {"0NB1KN", 'F'}, + {"0NB1KS", 'F'}, + {"0NB1KV", 'F'}, + {"0NB1O(", 'F'}, + {"0NB1OF", 'F'}, + {"0NB1OS", 'F'}, + {"0NB1OV", 'F'}, + {"0NB1U(", 'F'}, + {"0NB1UE", 'F'}, + {"0NBE((", 'F'}, + {"0NBE(1", 'F'}, + {"0NBE(F", 'F'}, + {"0NBE(N", 'F'}, + {"0NBE(S", 'F'}, + {"0NBE(V", 'F'}, + {"0NBEK(", 'F'}, + {"0NBF((", 'F'}, + {"0NBF()", 'F'}, + {"0NBF(1", 'F'}, + {"0NBF(F", 'F'}, + {"0NBF(N", 'F'}, + {"0NBF(S", 'F'}, + {"0NBF(V", 'F'}, + {"0NBN&(", 'F'}, + {"0NBN&1", 'F'}, + {"0NBN&F", 'F'}, + {"0NBN&N", 'F'}, + {"0NBN&S", 'F'}, + {"0NBN&V", 'F'}, + {"0NBN,(", 'F'}, + {"0NBN,F", 'F'}, + {"0NBN,V", 'F'}, + {"0NBN;", 'F'}, + {"0NBN;C", 'F'}, + {"0NBNB(", 'F'}, + {"0NBNB1", 'F'}, + {"0NBNBF", 'F'}, + {"0NBNBN", 'F'}, + {"0NBNBS", 'F'}, + {"0NBNBV", 'F'}, + {"0NBNC", 'F'}, + {"0NBNK(", 'F'}, + {"0NBNK1", 'F'}, + {"0NBNKF", 'F'}, + {"0NBNKN", 'F'}, + {"0NBNKS", 'F'}, + {"0NBNKV", 'F'}, + {"0NBNO(", 'F'}, + {"0NBNOF", 'F'}, + {"0NBNOS", 'F'}, + {"0NBNOV", 'F'}, + {"0NBNU(", 'F'}, + {"0NBNUE", 'F'}, + {"0NBS", 'F'}, + {"0NBS&(", 'F'}, + {"0NBS&1", 'F'}, + {"0NBS&F", 'F'}, + {"0NBS&N", 'F'}, + {"0NBS&S", 'F'}, + {"0NBS&V", 'F'}, + {"0NBS,(", 'F'}, + {"0NBS,F", 'F'}, + {"0NBS,V", 'F'}, + {"0NBS;", 'F'}, + {"0NBS;C", 'F'}, + {"0NBSB(", 'F'}, + {"0NBSB1", 'F'}, + {"0NBSBF", 'F'}, + {"0NBSBN", 'F'}, + {"0NBSBS", 'F'}, + {"0NBSBV", 'F'}, + {"0NBSC", 'F'}, + {"0NBSK(", 'F'}, + {"0NBSK1", 'F'}, + {"0NBSKF", 'F'}, + {"0NBSKN", 'F'}, + {"0NBSKS", 'F'}, + {"0NBSKV", 'F'}, + {"0NBSO(", 'F'}, + {"0NBSO1", 'F'}, + {"0NBSOF", 'F'}, + {"0NBSON", 'F'}, + {"0NBSOS", 'F'}, + {"0NBSOV", 'F'}, + {"0NBSU(", 'F'}, + {"0NBSUE", 'F'}, + {"0NBV", 'F'}, + {"0NBV&(", 'F'}, + {"0NBV&1", 'F'}, + {"0NBV&F", 'F'}, + {"0NBV&N", 'F'}, + {"0NBV&S", 'F'}, + {"0NBV&V", 'F'}, + {"0NBV,(", 'F'}, + {"0NBV,1", 'F'}, + {"0NBV,F", 'F'}, + {"0NBV,N", 'F'}, + {"0NBV,S", 'F'}, + {"0NBV,V", 'F'}, + {"0NBV;", 'F'}, + {"0NBV;C", 'F'}, + {"0NBVB(", 'F'}, + {"0NBVB1", 'F'}, + {"0NBVBF", 'F'}, + {"0NBVBN", 'F'}, + {"0NBVBS", 'F'}, + {"0NBVBV", 'F'}, + {"0NBVC", 'F'}, + {"0NBVK(", 'F'}, + {"0NBVK1", 'F'}, + {"0NBVKF", 'F'}, + {"0NBVKN", 'F'}, + {"0NBVKS", 'F'}, + {"0NBVKV", 'F'}, + {"0NBVO(", 'F'}, + {"0NBVOF", 'F'}, + {"0NBVOS", 'F'}, + {"0NBVU(", 'F'}, + {"0NBVUE", 'F'}, + {"0NC", 'F'}, + {"0NE(((", 'F'}, + {"0NE((1", 'F'}, + {"0NE((F", 'F'}, + {"0NE((N", 'F'}, + {"0NE((S", 'F'}, + {"0NE((V", 'F'}, + {"0NE(1)", 'F'}, + {"0NE(1O", 'F'}, + {"0NE(F(", 'F'}, + {"0NE(N)", 'F'}, + {"0NE(NO", 'F'}, + {"0NE(S)", 'F'}, + {"0NE(SO", 'F'}, + {"0NE(V)", 'F'}, + {"0NE(VO", 'F'}, + {"0NE1C", 'F'}, + {"0NE1O(", 'F'}, + {"0NE1OF", 'F'}, + {"0NE1OS", 'F'}, + {"0NE1OV", 'F'}, + {"0NE1UE", 'F'}, + {"0NEF((", 'F'}, + {"0NEF()", 'F'}, + {"0NEF(1", 'F'}, + {"0NEF(F", 'F'}, + {"0NEF(N", 'F'}, + {"0NEF(S", 'F'}, + {"0NEF(V", 'F'}, + {"0NENC", 'F'}, + {"0NENO(", 'F'}, + {"0NENOF", 'F'}, + {"0NENOS", 'F'}, + {"0NENOV", 'F'}, + {"0NENUE", 'F'}, + {"0NEOKN", 'F'}, + {"0NESC", 'F'}, + {"0NESO(", 'F'}, + {"0NESO1", 'F'}, + {"0NESOF", 'F'}, + {"0NESON", 'F'}, + {"0NESOS", 'F'}, + {"0NESOV", 'F'}, + {"0NESUE", 'F'}, + {"0NEU((", 'F'}, + {"0NEU(1", 'F'}, + {"0NEU(F", 'F'}, + {"0NEU(N", 'F'}, + {"0NEU(S", 'F'}, + {"0NEU(V", 'F'}, + {"0NEU1,", 'F'}, + {"0NEU1C", 'F'}, + {"0NEU1O", 'F'}, + {"0NEUEF", 'F'}, + {"0NEUEK", 'F'}, + {"0NEUF(", 'F'}, + {"0NEUN,", 'F'}, + {"0NEUNC", 'F'}, + {"0NEUNO", 'F'}, + {"0NEUS,", 'F'}, + {"0NEUSC", 'F'}, + {"0NEUSO", 'F'}, + {"0NEUV,", 'F'}, + {"0NEUVC", 'F'}, + {"0NEUVO", 'F'}, + {"0NEVC", 'F'}, + {"0NEVO(", 'F'}, + {"0NEVOF", 'F'}, + {"0NEVOS", 'F'}, + {"0NEVUE", 'F'}, + {"0NF(((", 'F'}, + {"0NF(()", 'F'}, + {"0NF((1", 'F'}, + {"0NF((F", 'F'}, + {"0NF((N", 'F'}, + {"0NF((S", 'F'}, + {"0NF((V", 'F'}, + {"0NF())", 'F'}, + {"0NF()1", 'F'}, + {"0NF()F", 'F'}, + {"0NF()K", 'F'}, + {"0NF()N", 'F'}, + {"0NF()O", 'F'}, + {"0NF()S", 'F'}, + {"0NF()U", 'F'}, + {"0NF()V", 'F'}, + {"0NF(1)", 'F'}, + {"0NF(1N", 'F'}, + {"0NF(1O", 'F'}, + {"0NF(F(", 'F'}, + {"0NF(N)", 'F'}, + {"0NF(N,", 'F'}, + {"0NF(NO", 'F'}, + {"0NF(S)", 'F'}, + {"0NF(SO", 'F'}, + {"0NF(V)", 'F'}, + {"0NF(VO", 'F'}, + {"0NK(((", 'F'}, + {"0NK((1", 'F'}, + {"0NK((F", 'F'}, + {"0NK((N", 'F'}, + {"0NK((S", 'F'}, + {"0NK((V", 'F'}, + {"0NK(1)", 'F'}, + {"0NK(1O", 'F'}, + {"0NK(F(", 'F'}, + {"0NK(N)", 'F'}, + {"0NK(NO", 'F'}, + {"0NK(S)", 'F'}, + {"0NK(SO", 'F'}, + {"0NK(V)", 'F'}, + {"0NK(VO", 'F'}, + {"0NK)&(", 'F'}, + {"0NK)&1", 'F'}, + {"0NK)&F", 'F'}, + {"0NK)&N", 'F'}, + {"0NK)&S", 'F'}, + {"0NK)&V", 'F'}, + {"0NK))&", 'F'}, + {"0NK)))", 'F'}, + {"0NK));", 'F'}, + {"0NK))B", 'F'}, + {"0NK))E", 'F'}, + {"0NK))K", 'F'}, + {"0NK))O", 'F'}, + {"0NK))U", 'F'}, + {"0NK);E", 'F'}, + {"0NK);T", 'F'}, + {"0NK)B(", 'F'}, + {"0NK)B1", 'F'}, + {"0NK)BF", 'F'}, + {"0NK)BN", 'F'}, + {"0NK)BS", 'F'}, + {"0NK)BV", 'F'}, + {"0NK)E(", 'F'}, + {"0NK)E1", 'F'}, + {"0NK)EF", 'F'}, + {"0NK)EK", 'F'}, + {"0NK)EN", 'F'}, + {"0NK)ES", 'F'}, + {"0NK)EV", 'F'}, + {"0NK)OF", 'F'}, + {"0NK)UE", 'F'}, + {"0NK1", 'F'}, + {"0NK1&(", 'F'}, + {"0NK1&1", 'F'}, + {"0NK1&F", 'F'}, + {"0NK1&N", 'F'}, + {"0NK1&S", 'F'}, + {"0NK1&V", 'F'}, + {"0NK1;C", 'F'}, + {"0NK1;E", 'F'}, + {"0NK1;T", 'F'}, + {"0NK1B(", 'F'}, + {"0NK1B1", 'F'}, + {"0NK1BF", 'F'}, + {"0NK1BN", 'F'}, + {"0NK1BS", 'F'}, + {"0NK1BV", 'F'}, + {"0NK1C", 'F'}, + {"0NK1E(", 'F'}, + {"0NK1E1", 'F'}, + {"0NK1EF", 'F'}, + {"0NK1EK", 'F'}, + {"0NK1EN", 'F'}, + {"0NK1ES", 'F'}, + {"0NK1EV", 'F'}, + {"0NK1O(", 'F'}, + {"0NK1OF", 'F'}, + {"0NK1OS", 'F'}, + {"0NK1OV", 'F'}, + {"0NK1U(", 'F'}, + {"0NK1UE", 'F'}, + {"0NKF((", 'F'}, + {"0NKF()", 'F'}, + {"0NKF(1", 'F'}, + {"0NKF(F", 'F'}, + {"0NKF(N", 'F'}, + {"0NKF(S", 'F'}, + {"0NKF(V", 'F'}, + {"0NKN", 'F'}, + {"0NKN&(", 'F'}, + {"0NKN&1", 'F'}, + {"0NKN&F", 'F'}, + {"0NKN&S", 'F'}, + {"0NKN&V", 'F'}, + {"0NKN;C", 'F'}, + {"0NKN;E", 'F'}, + {"0NKN;T", 'F'}, + {"0NKNB(", 'F'}, + {"0NKNB1", 'F'}, + {"0NKNBF", 'F'}, + {"0NKNBN", 'F'}, + {"0NKNBS", 'F'}, + {"0NKNBV", 'F'}, + {"0NKNC", 'F'}, + {"0NKNE(", 'F'}, + {"0NKNE1", 'F'}, + {"0NKNEF", 'F'}, + {"0NKNES", 'F'}, + {"0NKNEV", 'F'}, + {"0NKNU(", 'F'}, + {"0NKNUE", 'F'}, + {"0NKS", 'F'}, + {"0NKS&(", 'F'}, + {"0NKS&1", 'F'}, + {"0NKS&F", 'F'}, + {"0NKS&N", 'F'}, + {"0NKS&S", 'F'}, + {"0NKS&V", 'F'}, + {"0NKS;", 'F'}, + {"0NKS;C", 'F'}, + {"0NKS;E", 'F'}, + {"0NKS;T", 'F'}, + {"0NKSB(", 'F'}, + {"0NKSB1", 'F'}, + {"0NKSBF", 'F'}, + {"0NKSBN", 'F'}, + {"0NKSBS", 'F'}, + {"0NKSBV", 'F'}, + {"0NKSC", 'F'}, + {"0NKSE(", 'F'}, + {"0NKSE1", 'F'}, + {"0NKSEF", 'F'}, + {"0NKSEK", 'F'}, + {"0NKSEN", 'F'}, + {"0NKSES", 'F'}, + {"0NKSEV", 'F'}, + {"0NKSO(", 'F'}, + {"0NKSO1", 'F'}, + {"0NKSOF", 'F'}, + {"0NKSON", 'F'}, + {"0NKSOS", 'F'}, + {"0NKSOV", 'F'}, + {"0NKSU(", 'F'}, + {"0NKSUE", 'F'}, + {"0NKUE(", 'F'}, + {"0NKUE1", 'F'}, + {"0NKUEF", 'F'}, + {"0NKUEK", 'F'}, + {"0NKUEN", 'F'}, + {"0NKUES", 'F'}, + {"0NKUEV", 'F'}, + {"0NKV", 'F'}, + {"0NKV&(", 'F'}, + {"0NKV&1", 'F'}, + {"0NKV&F", 'F'}, + {"0NKV&N", 'F'}, + {"0NKV&S", 'F'}, + {"0NKV&V", 'F'}, + {"0NKV;", 'F'}, + {"0NKV;C", 'F'}, + {"0NKV;E", 'F'}, + {"0NKV;T", 'F'}, + {"0NKVB(", 'F'}, + {"0NKVB1", 'F'}, + {"0NKVBF", 'F'}, + {"0NKVBN", 'F'}, + {"0NKVBS", 'F'}, + {"0NKVBV", 'F'}, + {"0NKVC", 'F'}, + {"0NKVE(", 'F'}, + {"0NKVE1", 'F'}, + {"0NKVEF", 'F'}, + {"0NKVEK", 'F'}, + {"0NKVEN", 'F'}, + {"0NKVES", 'F'}, + {"0NKVEV", 'F'}, + {"0NKVO(", 'F'}, + {"0NKVOF", 'F'}, + {"0NKVOS", 'F'}, + {"0NKVU(", 'F'}, + {"0NKVUE", 'F'}, + {"0NO(((", 'F'}, + {"0NO((1", 'F'}, + {"0NO((E", 'F'}, + {"0NO((F", 'F'}, + {"0NO((N", 'F'}, + {"0NO((O", 'F'}, + {"0NO((S", 'F'}, + {"0NO((T", 'F'}, + {"0NO((V", 'F'}, + {"0NO(1&", 'F'}, + {"0NO(1)", 'F'}, + {"0NO(1,", 'F'}, + {"0NO(1O", 'F'}, + {"0NO(E(", 'F'}, + {"0NO(E1", 'F'}, + {"0NO(EE", 'F'}, + {"0NO(EF", 'F'}, + {"0NO(EK", 'F'}, + {"0NO(EN", 'F'}, + {"0NO(ES", 'F'}, + {"0NO(EV", 'F'}, + {"0NO(F(", 'F'}, + {"0NO(N&", 'F'}, + {"0NO(N)", 'F'}, + {"0NO(N,", 'F'}, + {"0NO(NO", 'F'}, + {"0NO(O(", 'F'}, + {"0NO(O1", 'F'}, + {"0NO(OF", 'F'}, + {"0NO(ON", 'F'}, + {"0NO(OS", 'F'}, + {"0NO(OV", 'F'}, + {"0NO(S&", 'F'}, + {"0NO(S)", 'F'}, + {"0NO(S,", 'F'}, + {"0NO(SO", 'F'}, + {"0NO(T(", 'F'}, + {"0NO(V&", 'F'}, + {"0NO(V)", 'F'}, + {"0NO(V,", 'F'}, + {"0NO(VO", 'F'}, + {"0NOF((", 'F'}, + {"0NOF()", 'F'}, + {"0NOF(1", 'F'}, + {"0NOF(E", 'F'}, + {"0NOF(F", 'F'}, + {"0NOF(N", 'F'}, + {"0NOF(S", 'F'}, + {"0NOF(V", 'F'}, + {"0NOK&(", 'F'}, + {"0NOK&1", 'F'}, + {"0NOK&F", 'F'}, + {"0NOK&N", 'F'}, + {"0NOK&S", 'F'}, + {"0NOK&V", 'F'}, + {"0NOK((", 'F'}, + {"0NOK(1", 'F'}, + {"0NOK(F", 'F'}, + {"0NOK(N", 'F'}, + {"0NOK(S", 'F'}, + {"0NOK(V", 'F'}, + {"0NOK1C", 'F'}, + {"0NOK1O", 'F'}, + {"0NOKF(", 'F'}, + {"0NOKNC", 'F'}, + {"0NOKO(", 'F'}, + {"0NOKO1", 'F'}, + {"0NOKOF", 'F'}, + {"0NOKON", 'F'}, + {"0NOKOS", 'F'}, + {"0NOKOV", 'F'}, + {"0NOKSC", 'F'}, + {"0NOKSO", 'F'}, + {"0NOKVC", 'F'}, + {"0NOKVO", 'F'}, + {"0NONSU", 'F'}, + {"0NOS&(", 'F'}, + {"0NOS&1", 'F'}, + {"0NOS&E", 'F'}, + {"0NOS&F", 'F'}, + {"0NOS&K", 'F'}, + {"0NOS&N", 'F'}, + {"0NOS&S", 'F'}, + {"0NOS&U", 'F'}, + {"0NOS&V", 'F'}, + {"0NOS((", 'F'}, + {"0NOS(E", 'F'}, + {"0NOS(U", 'F'}, + {"0NOS)&", 'F'}, + {"0NOS))", 'F'}, + {"0NOS),", 'F'}, + {"0NOS);", 'F'}, + {"0NOS)B", 'F'}, + {"0NOS)E", 'F'}, + {"0NOS)K", 'F'}, + {"0NOS)O", 'F'}, + {"0NOS)U", 'F'}, + {"0NOS,(", 'F'}, + {"0NOS,F", 'F'}, + {"0NOS,V", 'F'}, + {"0NOS1(", 'F'}, + {"0NOS1F", 'F'}, + {"0NOS1N", 'F'}, + {"0NOS1O", 'F'}, + {"0NOS1S", 'F'}, + {"0NOS1U", 'F'}, + {"0NOS1V", 'F'}, + {"0NOS;", 'F'}, + {"0NOS;C", 'F'}, + {"0NOS;E", 'F'}, + {"0NOS;T", 'F'}, + {"0NOSA(", 'F'}, + {"0NOSAF", 'F'}, + {"0NOSAS", 'F'}, + {"0NOSAT", 'F'}, + {"0NOSAV", 'F'}, + {"0NOSB(", 'F'}, + {"0NOSB1", 'F'}, + {"0NOSBE", 'F'}, + {"0NOSBF", 'F'}, + {"0NOSBN", 'F'}, + {"0NOSBS", 'F'}, + {"0NOSBV", 'F'}, + {"0NOSC", 'F'}, + {"0NOSE(", 'F'}, + {"0NOSE1", 'F'}, + {"0NOSEF", 'F'}, + {"0NOSEK", 'F'}, + {"0NOSEN", 'F'}, + {"0NOSEO", 'F'}, + {"0NOSES", 'F'}, + {"0NOSEU", 'F'}, + {"0NOSEV", 'F'}, + {"0NOSF(", 'F'}, + {"0NOSK(", 'F'}, + {"0NOSK)", 'F'}, + {"0NOSK1", 'F'}, + {"0NOSKB", 'F'}, + {"0NOSKF", 'F'}, + {"0NOSKN", 'F'}, + {"0NOSKS", 'F'}, + {"0NOSKU", 'F'}, + {"0NOSKV", 'F'}, + {"0NOSO(", 'F'}, + {"0NOSO1", 'F'}, + {"0NOSOF", 'F'}, + {"0NOSOK", 'F'}, + {"0NOSON", 'F'}, + {"0NOSOS", 'F'}, + {"0NOSOT", 'F'}, + {"0NOSOU", 'F'}, + {"0NOSOV", 'F'}, + {"0NOSU", 'F'}, + {"0NOSU(", 'F'}, + {"0NOSU1", 'F'}, + {"0NOSU;", 'F'}, + {"0NOSUC", 'F'}, + {"0NOSUE", 'F'}, + {"0NOSUF", 'F'}, + {"0NOSUK", 'F'}, + {"0NOSUN", 'F'}, + {"0NOSUO", 'F'}, + {"0NOSUS", 'F'}, + {"0NOSUT", 'F'}, + {"0NOSUV", 'F'}, + {"0NOSV(", 'F'}, + {"0NOSVF", 'F'}, + {"0NOSVO", 'F'}, + {"0NOSVS", 'F'}, + {"0NOSVU", 'F'}, + {"0NOT((", 'F'}, + {"0NOT(1", 'F'}, + {"0NOT(F", 'F'}, + {"0NOT(N", 'F'}, + {"0NOT(S", 'F'}, + {"0NOT(V", 'F'}, + {"0NOU((", 'F'}, + {"0NOU(E", 'F'}, + {"0NOUEK", 'F'}, + {"0NOUEN", 'F'}, + {"0NOV&(", 'F'}, + {"0NOV&1", 'F'}, + {"0NOV&E", 'F'}, + {"0NOV&F", 'F'}, + {"0NOV&K", 'F'}, + {"0NOV&N", 'F'}, + {"0NOV&S", 'F'}, + {"0NOV&U", 'F'}, + {"0NOV&V", 'F'}, + {"0NOV((", 'F'}, + {"0NOV(E", 'F'}, + {"0NOV(U", 'F'}, + {"0NOV)&", 'F'}, + {"0NOV))", 'F'}, + {"0NOV),", 'F'}, + {"0NOV);", 'F'}, + {"0NOV)B", 'F'}, + {"0NOV)E", 'F'}, + {"0NOV)K", 'F'}, + {"0NOV)O", 'F'}, + {"0NOV)U", 'F'}, + {"0NOV,(", 'F'}, + {"0NOV,1", 'F'}, + {"0NOV,F", 'F'}, + {"0NOV,N", 'F'}, + {"0NOV,S", 'F'}, + {"0NOV,V", 'F'}, + {"0NOV;", 'F'}, + {"0NOV;C", 'F'}, + {"0NOV;E", 'F'}, + {"0NOV;N", 'F'}, + {"0NOV;T", 'F'}, + {"0NOVA(", 'F'}, + {"0NOVAF", 'F'}, + {"0NOVAS", 'F'}, + {"0NOVAT", 'F'}, + {"0NOVAV", 'F'}, + {"0NOVB(", 'F'}, + {"0NOVB1", 'F'}, + {"0NOVBE", 'F'}, + {"0NOVBF", 'F'}, + {"0NOVBN", 'F'}, + {"0NOVBS", 'F'}, + {"0NOVBV", 'F'}, + {"0NOVC", 'F'}, + {"0NOVE(", 'F'}, + {"0NOVE1", 'F'}, + {"0NOVEF", 'F'}, + {"0NOVEK", 'F'}, + {"0NOVEN", 'F'}, + {"0NOVEO", 'F'}, + {"0NOVES", 'F'}, + {"0NOVEU", 'F'}, + {"0NOVEV", 'F'}, + {"0NOVF(", 'F'}, + {"0NOVK(", 'F'}, + {"0NOVK)", 'F'}, + {"0NOVK1", 'F'}, + {"0NOVKB", 'F'}, + {"0NOVKF", 'F'}, + {"0NOVKN", 'F'}, + {"0NOVKS", 'F'}, + {"0NOVKU", 'F'}, + {"0NOVKV", 'F'}, + {"0NOVO(", 'F'}, + {"0NOVOF", 'F'}, + {"0NOVOK", 'F'}, + {"0NOVOS", 'F'}, + {"0NOVOT", 'F'}, + {"0NOVOU", 'F'}, + {"0NOVS(", 'F'}, + {"0NOVS1", 'F'}, + {"0NOVSF", 'F'}, + {"0NOVSO", 'F'}, + {"0NOVSU", 'F'}, + {"0NOVSV", 'F'}, + {"0NOVU", 'F'}, + {"0NOVU(", 'F'}, + {"0NOVU1", 'F'}, + {"0NOVU;", 'F'}, + {"0NOVUC", 'F'}, + {"0NOVUE", 'F'}, + {"0NOVUF", 'F'}, + {"0NOVUK", 'F'}, + {"0NOVUN", 'F'}, + {"0NOVUO", 'F'}, + {"0NOVUS", 'F'}, + {"0NOVUT", 'F'}, + {"0NOVUV", 'F'}, + {"0NSO1U", 'F'}, + {"0NSONU", 'F'}, + {"0NSOSU", 'F'}, + {"0NSOVU", 'F'}, + {"0NSUE", 'F'}, + {"0NSUE;", 'F'}, + {"0NSUEC", 'F'}, + {"0NSUEK", 'F'}, + {"0NU(((", 'F'}, + {"0NU((1", 'F'}, + {"0NU((E", 'F'}, + {"0NU((F", 'F'}, + {"0NU((N", 'F'}, + {"0NU((S", 'F'}, + {"0NU((V", 'F'}, + {"0NU(1)", 'F'}, + {"0NU(1O", 'F'}, + {"0NU(E(", 'F'}, + {"0NU(E1", 'F'}, + {"0NU(EF", 'F'}, + {"0NU(EK", 'F'}, + {"0NU(EN", 'F'}, + {"0NU(ES", 'F'}, + {"0NU(EV", 'F'}, + {"0NU(F(", 'F'}, + {"0NU(N)", 'F'}, + {"0NU(NO", 'F'}, + {"0NU(S)", 'F'}, + {"0NU(SO", 'F'}, + {"0NU(V)", 'F'}, + {"0NU(VO", 'F'}, + {"0NU1,(", 'F'}, + {"0NU1,F", 'F'}, + {"0NU1,V", 'F'}, + {"0NU1C", 'F'}, + {"0NU1O(", 'F'}, + {"0NU1OF", 'F'}, + {"0NU1OS", 'F'}, + {"0NU1OV", 'F'}, + {"0NU;", 'F'}, + {"0NU;C", 'F'}, + {"0NUC", 'F'}, + {"0NUE", 'F'}, + {"0NUE((", 'F'}, + {"0NUE(1", 'F'}, + {"0NUE(E", 'F'}, + {"0NUE(F", 'F'}, + {"0NUE(N", 'F'}, + {"0NUE(O", 'F'}, + {"0NUE(S", 'F'}, + {"0NUE(V", 'F'}, + {"0NUE1", 'F'}, + {"0NUE1&", 'F'}, + {"0NUE1(", 'F'}, + {"0NUE1)", 'F'}, + {"0NUE1,", 'F'}, + {"0NUE1;", 'F'}, + {"0NUE1B", 'F'}, + {"0NUE1C", 'F'}, + {"0NUE1F", 'F'}, + {"0NUE1K", 'F'}, + {"0NUE1N", 'F'}, + {"0NUE1O", 'F'}, + {"0NUE1S", 'F'}, + {"0NUE1U", 'F'}, + {"0NUE1V", 'F'}, + {"0NUE;", 'F'}, + {"0NUE;C", 'F'}, + {"0NUEC", 'F'}, + {"0NUEF", 'F'}, + {"0NUEF(", 'F'}, + {"0NUEF,", 'F'}, + {"0NUEF;", 'F'}, + {"0NUEFC", 'F'}, + {"0NUEK", 'F'}, + {"0NUEK(", 'F'}, + {"0NUEK1", 'F'}, + {"0NUEK;", 'F'}, + {"0NUEKC", 'F'}, + {"0NUEKF", 'F'}, + {"0NUEKN", 'F'}, + {"0NUEKO", 'F'}, + {"0NUEKS", 'F'}, + {"0NUEKV", 'F'}, + {"0NUEN", 'F'}, + {"0NUEN&", 'F'}, + {"0NUEN(", 'F'}, + {"0NUEN)", 'F'}, + {"0NUEN,", 'F'}, + {"0NUEN1", 'F'}, + {"0NUEN;", 'F'}, + {"0NUENB", 'F'}, + {"0NUENC", 'F'}, + {"0NUENF", 'F'}, + {"0NUENK", 'F'}, + {"0NUENO", 'F'}, + {"0NUENS", 'F'}, + {"0NUENU", 'F'}, + {"0NUEOK", 'F'}, + {"0NUEON", 'F'}, + {"0NUEOO", 'F'}, + {"0NUES", 'F'}, + {"0NUES&", 'F'}, + {"0NUES(", 'F'}, + {"0NUES)", 'F'}, + {"0NUES,", 'F'}, + {"0NUES1", 'F'}, + {"0NUES;", 'F'}, + {"0NUESB", 'F'}, + {"0NUESC", 'F'}, + {"0NUESF", 'F'}, + {"0NUESK", 'F'}, + {"0NUESO", 'F'}, + {"0NUESU", 'F'}, + {"0NUESV", 'F'}, + {"0NUEV", 'F'}, + {"0NUEV&", 'F'}, + {"0NUEV(", 'F'}, + {"0NUEV)", 'F'}, + {"0NUEV,", 'F'}, + {"0NUEV;", 'F'}, + {"0NUEVB", 'F'}, + {"0NUEVC", 'F'}, + {"0NUEVF", 'F'}, + {"0NUEVK", 'F'}, + {"0NUEVN", 'F'}, + {"0NUEVO", 'F'}, + {"0NUEVS", 'F'}, + {"0NUEVU", 'F'}, + {"0NUF((", 'F'}, + {"0NUF()", 'F'}, + {"0NUF(1", 'F'}, + {"0NUF(F", 'F'}, + {"0NUF(N", 'F'}, + {"0NUF(S", 'F'}, + {"0NUF(V", 'F'}, + {"0NUK((", 'F'}, + {"0NUK(E", 'F'}, + {"0NUN((", 'F'}, + {"0NUN(1", 'F'}, + {"0NUN(F", 'F'}, + {"0NUN(S", 'F'}, + {"0NUN(V", 'F'}, + {"0NUN,(", 'F'}, + {"0NUN,F", 'F'}, + {"0NUN,V", 'F'}, + {"0NUN1(", 'F'}, + {"0NUN1,", 'F'}, + {"0NUN1O", 'F'}, + {"0NUNC", 'F'}, + {"0NUNE(", 'F'}, + {"0NUNE1", 'F'}, + {"0NUNEF", 'F'}, + {"0NUNEN", 'F'}, + {"0NUNES", 'F'}, + {"0NUNEV", 'F'}, + {"0NUNF(", 'F'}, + {"0NUNO(", 'F'}, + {"0NUNOF", 'F'}, + {"0NUNOS", 'F'}, + {"0NUNOV", 'F'}, + {"0NUNS(", 'F'}, + {"0NUNS,", 'F'}, + {"0NUNSO", 'F'}, + {"0NUO((", 'F'}, + {"0NUO(E", 'F'}, + {"0NUON(", 'F'}, + {"0NUON1", 'F'}, + {"0NUONF", 'F'}, + {"0NUONS", 'F'}, + {"0NUS,(", 'F'}, + {"0NUS,F", 'F'}, + {"0NUS,V", 'F'}, + {"0NUSC", 'F'}, + {"0NUSO(", 'F'}, + {"0NUSO1", 'F'}, + {"0NUSOF", 'F'}, + {"0NUSON", 'F'}, + {"0NUSOS", 'F'}, + {"0NUSOV", 'F'}, + {"0NUTN(", 'F'}, + {"0NUTN1", 'F'}, + {"0NUTNF", 'F'}, + {"0NUTNS", 'F'}, + {"0NUV,(", 'F'}, + {"0NUV,1", 'F'}, + {"0NUV,F", 'F'}, + {"0NUV,N", 'F'}, + {"0NUV,S", 'F'}, + {"0NUV,V", 'F'}, + {"0NUVC", 'F'}, + {"0NUVO(", 'F'}, + {"0NUVOF", 'F'}, + {"0NUVOS", 'F'}, + {"0OF(((", 'F'}, + {"0OF((1", 'F'}, + {"0OF((F", 'F'}, + {"0OF((N", 'F'}, + {"0OF((S", 'F'}, + {"0OF((V", 'F'}, + {"0OF(1O", 'F'}, + {"0OF(F(", 'F'}, + {"0OF(NO", 'F'}, + {"0OF(SO", 'F'}, + {"0OF(VO", 'F'}, + {"0OUE((", 'F'}, + {"0OUE(1", 'F'}, + {"0OUE(F", 'F'}, + {"0OUE(N", 'F'}, + {"0OUE(S", 'F'}, + {"0OUE(V", 'F'}, + {"0OUE1,", 'F'}, + {"0OUE1O", 'F'}, + {"0OUEF(", 'F'}, + {"0OUEK(", 'F'}, + {"0OUEK1", 'F'}, + {"0OUEKF", 'F'}, + {"0OUEKN", 'F'}, + {"0OUEKS", 'F'}, + {"0OUEKV", 'F'}, + {"0OUEN,", 'F'}, + {"0OUENO", 'F'}, + {"0OUES,", 'F'}, + {"0OUESO", 'F'}, + {"0OUEV,", 'F'}, + {"0OUEVO", 'F'}, + {"0S&(((", 'F'}, + {"0S&((1", 'F'}, + {"0S&((E", 'F'}, + {"0S&((F", 'F'}, + {"0S&((N", 'F'}, + {"0S&((S", 'F'}, + {"0S&((V", 'F'}, + {"0S&(1&", 'F'}, + {"0S&(1)", 'F'}, + {"0S&(1,", 'F'}, + {"0S&(1O", 'F'}, + {"0S&(E(", 'F'}, + {"0S&(E1", 'F'}, + {"0S&(EF", 'F'}, + {"0S&(EK", 'F'}, + {"0S&(EN", 'F'}, + {"0S&(EO", 'F'}, + {"0S&(ES", 'F'}, + {"0S&(EV", 'F'}, + {"0S&(F(", 'F'}, + {"0S&(N&", 'F'}, + {"0S&(N)", 'F'}, + {"0S&(N,", 'F'}, + {"0S&(NO", 'F'}, + {"0S&(S&", 'F'}, + {"0S&(S)", 'F'}, + {"0S&(S,", 'F'}, + {"0S&(SO", 'F'}, + {"0S&(V&", 'F'}, + {"0S&(V)", 'F'}, + {"0S&(V,", 'F'}, + {"0S&(VO", 'F'}, + {"0S&1", 'F'}, + {"0S&1&(", 'F'}, + {"0S&1&1", 'F'}, + {"0S&1&F", 'F'}, + {"0S&1&N", 'F'}, + {"0S&1&S", 'F'}, + {"0S&1&V", 'F'}, + {"0S&1)&", 'F'}, + {"0S&1))", 'F'}, + {"0S&1)U", 'F'}, + {"0S&1;", 'F'}, + {"0S&1;C", 'F'}, + {"0S&1;E", 'F'}, + {"0S&1;T", 'F'}, + {"0S&1B(", 'F'}, + {"0S&1B1", 'F'}, + {"0S&1BF", 'F'}, + {"0S&1BN", 'F'}, + {"0S&1BS", 'F'}, + {"0S&1BV", 'F'}, + {"0S&1C", 'F'}, + {"0S&1EK", 'F'}, + {"0S&1EN", 'F'}, + {"0S&1F(", 'F'}, + {"0S&1K(", 'F'}, + {"0S&1K1", 'F'}, + {"0S&1KF", 'F'}, + {"0S&1KN", 'F'}, + {"0S&1KS", 'F'}, + {"0S&1KV", 'F'}, + {"0S&1O(", 'F'}, + {"0S&1OF", 'F'}, + {"0S&1OO", 'F'}, + {"0S&1OS", 'F'}, + {"0S&1OV", 'F'}, + {"0S&1S", 'F'}, + {"0S&1TN", 'F'}, + {"0S&1U", 'F'}, + {"0S&1U(", 'F'}, + {"0S&1U;", 'F'}, + {"0S&1UC", 'F'}, + {"0S&1UE", 'F'}, + {"0S&E((", 'F'}, + {"0S&E(1", 'F'}, + {"0S&E(F", 'F'}, + {"0S&E(N", 'F'}, + {"0S&E(O", 'F'}, + {"0S&E(S", 'F'}, + {"0S&E(V", 'F'}, + {"0S&E1", 'F'}, + {"0S&E1;", 'F'}, + {"0S&E1C", 'F'}, + {"0S&E1K", 'F'}, + {"0S&E1O", 'F'}, + {"0S&EF(", 'F'}, + {"0S&EK(", 'F'}, + {"0S&EK1", 'F'}, + {"0S&EKF", 'F'}, + {"0S&EKN", 'F'}, + {"0S&EKS", 'F'}, + {"0S&EKV", 'F'}, + {"0S&EN", 'F'}, + {"0S&EN;", 'F'}, + {"0S&ENC", 'F'}, + {"0S&ENK", 'F'}, + {"0S&ENO", 'F'}, + {"0S&ES", 'F'}, + {"0S&ES;", 'F'}, + {"0S&ESC", 'F'}, + {"0S&ESK", 'F'}, + {"0S&ESO", 'F'}, + {"0S&EV", 'F'}, + {"0S&EV;", 'F'}, + {"0S&EVC", 'F'}, + {"0S&EVK", 'F'}, + {"0S&EVO", 'F'}, + {"0S&F((", 'F'}, + {"0S&F()", 'F'}, + {"0S&F(1", 'F'}, + {"0S&F(F", 'F'}, + {"0S&F(N", 'F'}, + {"0S&F(S", 'F'}, + {"0S&F(V", 'F'}, + {"0S&K&(", 'F'}, + {"0S&K&1", 'F'}, + {"0S&K&F", 'F'}, + {"0S&K&N", 'F'}, + {"0S&K&S", 'F'}, + {"0S&K&V", 'F'}, + {"0S&K((", 'F'}, + {"0S&K(1", 'F'}, + {"0S&K(F", 'F'}, + {"0S&K(N", 'F'}, + {"0S&K(S", 'F'}, + {"0S&K(V", 'F'}, + {"0S&K1O", 'F'}, + {"0S&KF(", 'F'}, + {"0S&KNK", 'F'}, + {"0S&KO(", 'F'}, + {"0S&KO1", 'F'}, + {"0S&KOF", 'F'}, + {"0S&KOK", 'F'}, + {"0S&KON", 'F'}, + {"0S&KOS", 'F'}, + {"0S&KOV", 'F'}, + {"0S&KSO", 'F'}, + {"0S&KVO", 'F'}, + {"0S&N", 'F'}, + {"0S&N&(", 'F'}, + {"0S&N&1", 'F'}, + {"0S&N&F", 'F'}, + {"0S&N&N", 'F'}, + {"0S&N&S", 'F'}, + {"0S&N&V", 'F'}, + {"0S&N)&", 'F'}, + {"0S&N))", 'F'}, + {"0S&N)U", 'F'}, + {"0S&N;", 'F'}, + {"0S&N;C", 'F'}, + {"0S&N;E", 'F'}, + {"0S&N;T", 'F'}, + {"0S&NB(", 'F'}, + {"0S&NB1", 'F'}, + {"0S&NBF", 'F'}, + {"0S&NBN", 'F'}, + {"0S&NBS", 'F'}, + {"0S&NBV", 'F'}, + {"0S&NC", 'F'}, + {"0S&NEN", 'F'}, + {"0S&NF(", 'F'}, + {"0S&NK(", 'F'}, + {"0S&NK1", 'F'}, + {"0S&NKF", 'F'}, + {"0S&NKN", 'F'}, + {"0S&NKS", 'F'}, + {"0S&NKV", 'F'}, + {"0S&NO(", 'F'}, + {"0S&NOF", 'F'}, + {"0S&NOS", 'F'}, + {"0S&NOV", 'F'}, + {"0S&NTN", 'F'}, + {"0S&NU", 'F'}, + {"0S&NU(", 'F'}, + {"0S&NU;", 'F'}, + {"0S&NUC", 'F'}, + {"0S&NUE", 'F'}, + {"0S&S", 'F'}, + {"0S&S&(", 'F'}, + {"0S&S&1", 'F'}, + {"0S&S&F", 'F'}, + {"0S&S&N", 'F'}, + {"0S&S&S", 'F'}, + {"0S&S&V", 'F'}, + {"0S&S)&", 'F'}, + {"0S&S))", 'F'}, + {"0S&S)U", 'F'}, + {"0S&S1", 'F'}, + {"0S&S1;", 'F'}, + {"0S&S1C", 'F'}, + {"0S&S1O", 'F'}, + {"0S&S;", 'F'}, + {"0S&S;C", 'F'}, + {"0S&S;E", 'F'}, + {"0S&S;T", 'F'}, + {"0S&SB(", 'F'}, + {"0S&SB1", 'F'}, + {"0S&SBF", 'F'}, + {"0S&SBN", 'F'}, + {"0S&SBS", 'F'}, + {"0S&SBV", 'F'}, + {"0S&SC", 'F'}, + {"0S&SEK", 'F'}, + {"0S&SEN", 'F'}, + {"0S&SF(", 'F'}, + {"0S&SK(", 'F'}, + {"0S&SK1", 'F'}, + {"0S&SKF", 'F'}, + {"0S&SKN", 'F'}, + {"0S&SKS", 'F'}, + {"0S&SKV", 'F'}, + {"0S&SO(", 'F'}, + {"0S&SO1", 'F'}, + {"0S&SOF", 'F'}, + {"0S&SON", 'F'}, + {"0S&SOO", 'F'}, + {"0S&SOS", 'F'}, + {"0S&SOV", 'F'}, + {"0S&STN", 'F'}, + {"0S&SU", 'F'}, + {"0S&SU(", 'F'}, + {"0S&SU;", 'F'}, + {"0S&SUC", 'F'}, + {"0S&SUE", 'F'}, + {"0S&SV", 'F'}, + {"0S&SV;", 'F'}, + {"0S&SVC", 'F'}, + {"0S&SVO", 'F'}, + {"0S&V", 'F'}, + {"0S&V&(", 'F'}, + {"0S&V&1", 'F'}, + {"0S&V&F", 'F'}, + {"0S&V&N", 'F'}, + {"0S&V&S", 'F'}, + {"0S&V&V", 'F'}, + {"0S&V)&", 'F'}, + {"0S&V))", 'F'}, + {"0S&V)U", 'F'}, + {"0S&V;", 'F'}, + {"0S&V;C", 'F'}, + {"0S&V;E", 'F'}, + {"0S&V;T", 'F'}, + {"0S&VB(", 'F'}, + {"0S&VB1", 'F'}, + {"0S&VBF", 'F'}, + {"0S&VBN", 'F'}, + {"0S&VBS", 'F'}, + {"0S&VBV", 'F'}, + {"0S&VC", 'F'}, + {"0S&VEK", 'F'}, + {"0S&VEN", 'F'}, + {"0S&VF(", 'F'}, + {"0S&VK(", 'F'}, + {"0S&VK1", 'F'}, + {"0S&VKF", 'F'}, + {"0S&VKN", 'F'}, + {"0S&VKS", 'F'}, + {"0S&VKV", 'F'}, + {"0S&VO(", 'F'}, + {"0S&VOF", 'F'}, + {"0S&VOO", 'F'}, + {"0S&VOS", 'F'}, + {"0S&VS", 'F'}, + {"0S&VS;", 'F'}, + {"0S&VSC", 'F'}, + {"0S&VSO", 'F'}, + {"0S&VTN", 'F'}, + {"0S&VU", 'F'}, + {"0S&VU(", 'F'}, + {"0S&VU;", 'F'}, + {"0S&VUC", 'F'}, + {"0S&VUE", 'F'}, + {"0S((((", 'F'}, + {"0S(((E", 'F'}, + {"0S(((U", 'F'}, + {"0S((EK", 'F'}, + {"0S((EN", 'F'}, + {"0S((U(", 'F'}, + {"0S(EKN", 'F'}, + {"0S(ENK", 'F'}, + {"0S(U((", 'F'}, + {"0S(U(E", 'F'}, + {"0S)&((", 'F'}, + {"0S)&(1", 'F'}, + {"0S)&(E", 'F'}, + {"0S)&(F", 'F'}, + {"0S)&(N", 'F'}, + {"0S)&(S", 'F'}, + {"0S)&(V", 'F'}, + {"0S)&1", 'F'}, + {"0S)&1&", 'F'}, + {"0S)&1)", 'F'}, + {"0S)&1;", 'F'}, + {"0S)&1B", 'F'}, + {"0S)&1C", 'F'}, + {"0S)&1F", 'F'}, + {"0S)&1O", 'F'}, + {"0S)&1U", 'F'}, + {"0S)&F(", 'F'}, + {"0S)&N", 'F'}, + {"0S)&N&", 'F'}, + {"0S)&N)", 'F'}, + {"0S)&N;", 'F'}, + {"0S)&NB", 'F'}, + {"0S)&NC", 'F'}, + {"0S)&NF", 'F'}, + {"0S)&NO", 'F'}, + {"0S)&NU", 'F'}, + {"0S)&S", 'F'}, + {"0S)&S&", 'F'}, + {"0S)&S)", 'F'}, + {"0S)&S;", 'F'}, + {"0S)&SB", 'F'}, + {"0S)&SC", 'F'}, + {"0S)&SF", 'F'}, + {"0S)&SO", 'F'}, + {"0S)&SU", 'F'}, + {"0S)&V", 'F'}, + {"0S)&V&", 'F'}, + {"0S)&V)", 'F'}, + {"0S)&V;", 'F'}, + {"0S)&VB", 'F'}, + {"0S)&VC", 'F'}, + {"0S)&VF", 'F'}, + {"0S)&VO", 'F'}, + {"0S)&VU", 'F'}, + {"0S))&(", 'F'}, + {"0S))&1", 'F'}, + {"0S))&F", 'F'}, + {"0S))&N", 'F'}, + {"0S))&S", 'F'}, + {"0S))&V", 'F'}, + {"0S)))&", 'F'}, + {"0S))))", 'F'}, + {"0S))),", 'F'}, + {"0S)));", 'F'}, + {"0S)))B", 'F'}, + {"0S)))E", 'F'}, + {"0S)))K", 'F'}, + {"0S)))O", 'F'}, + {"0S)))U", 'F'}, + {"0S)),(", 'F'}, + {"0S));E", 'F'}, + {"0S));T", 'F'}, + {"0S))B(", 'F'}, + {"0S))B1", 'F'}, + {"0S))BF", 'F'}, + {"0S))BN", 'F'}, + {"0S))BS", 'F'}, + {"0S))BV", 'F'}, + {"0S))E(", 'F'}, + {"0S))E1", 'F'}, + {"0S))EF", 'F'}, + {"0S))EK", 'F'}, + {"0S))EN", 'F'}, + {"0S))ES", 'F'}, + {"0S))EV", 'F'}, + {"0S))K(", 'F'}, + {"0S))K1", 'F'}, + {"0S))KB", 'F'}, + {"0S))KF", 'F'}, + {"0S))KN", 'F'}, + {"0S))KS", 'F'}, + {"0S))KU", 'F'}, + {"0S))KV", 'F'}, + {"0S))O(", 'F'}, + {"0S))O1", 'F'}, + {"0S))OF", 'F'}, + {"0S))ON", 'F'}, + {"0S))OS", 'F'}, + {"0S))OV", 'F'}, + {"0S))U(", 'F'}, + {"0S))UE", 'F'}, + {"0S),((", 'F'}, + {"0S),(1", 'F'}, + {"0S),(F", 'F'}, + {"0S),(N", 'F'}, + {"0S),(S", 'F'}, + {"0S),(V", 'F'}, + {"0S);E(", 'F'}, + {"0S);E1", 'F'}, + {"0S);EF", 'F'}, + {"0S);EK", 'F'}, + {"0S);EN", 'F'}, + {"0S);EO", 'F'}, + {"0S);ES", 'F'}, + {"0S);EV", 'F'}, + {"0S);T(", 'F'}, + {"0S);T1", 'F'}, + {"0S);TF", 'F'}, + {"0S);TK", 'F'}, + {"0S);TN", 'F'}, + {"0S);TO", 'F'}, + {"0S);TS", 'F'}, + {"0S);TV", 'F'}, + {"0S)B((", 'F'}, + {"0S)B(1", 'F'}, + {"0S)B(F", 'F'}, + {"0S)B(N", 'F'}, + {"0S)B(S", 'F'}, + {"0S)B(V", 'F'}, + {"0S)B1", 'F'}, + {"0S)B1&", 'F'}, + {"0S)B1;", 'F'}, + {"0S)B1C", 'F'}, + {"0S)B1K", 'F'}, + {"0S)B1N", 'F'}, + {"0S)B1O", 'F'}, + {"0S)B1U", 'F'}, + {"0S)BF(", 'F'}, + {"0S)BN", 'F'}, + {"0S)BN&", 'F'}, + {"0S)BN;", 'F'}, + {"0S)BNC", 'F'}, + {"0S)BNK", 'F'}, + {"0S)BNO", 'F'}, + {"0S)BNU", 'F'}, + {"0S)BS", 'F'}, + {"0S)BS&", 'F'}, + {"0S)BS;", 'F'}, + {"0S)BSC", 'F'}, + {"0S)BSK", 'F'}, + {"0S)BSO", 'F'}, + {"0S)BSU", 'F'}, + {"0S)BV", 'F'}, + {"0S)BV&", 'F'}, + {"0S)BV;", 'F'}, + {"0S)BVC", 'F'}, + {"0S)BVK", 'F'}, + {"0S)BVO", 'F'}, + {"0S)BVU", 'F'}, + {"0S)E((", 'F'}, + {"0S)E(1", 'F'}, + {"0S)E(F", 'F'}, + {"0S)E(N", 'F'}, + {"0S)E(S", 'F'}, + {"0S)E(V", 'F'}, + {"0S)E1C", 'F'}, + {"0S)E1O", 'F'}, + {"0S)EF(", 'F'}, + {"0S)EK(", 'F'}, + {"0S)EK1", 'F'}, + {"0S)EKF", 'F'}, + {"0S)EKN", 'F'}, + {"0S)EKS", 'F'}, + {"0S)EKV", 'F'}, + {"0S)ENC", 'F'}, + {"0S)ENO", 'F'}, + {"0S)ESC", 'F'}, + {"0S)ESO", 'F'}, + {"0S)EVC", 'F'}, + {"0S)EVO", 'F'}, + {"0S)K((", 'F'}, + {"0S)K(1", 'F'}, + {"0S)K(F", 'F'}, + {"0S)K(N", 'F'}, + {"0S)K(S", 'F'}, + {"0S)K(V", 'F'}, + {"0S)K1&", 'F'}, + {"0S)K1;", 'F'}, + {"0S)K1B", 'F'}, + {"0S)K1E", 'F'}, + {"0S)K1O", 'F'}, + {"0S)K1U", 'F'}, + {"0S)KB(", 'F'}, + {"0S)KB1", 'F'}, + {"0S)KBF", 'F'}, + {"0S)KBN", 'F'}, + {"0S)KBS", 'F'}, + {"0S)KBV", 'F'}, + {"0S)KF(", 'F'}, + {"0S)KN&", 'F'}, + {"0S)KN;", 'F'}, + {"0S)KNB", 'F'}, + {"0S)KNE", 'F'}, + {"0S)KNK", 'F'}, + {"0S)KNU", 'F'}, + {"0S)KS&", 'F'}, + {"0S)KS;", 'F'}, + {"0S)KSB", 'F'}, + {"0S)KSE", 'F'}, + {"0S)KSO", 'F'}, + {"0S)KSU", 'F'}, + {"0S)KUE", 'F'}, + {"0S)KV&", 'F'}, + {"0S)KV;", 'F'}, + {"0S)KVB", 'F'}, + {"0S)KVE", 'F'}, + {"0S)KVO", 'F'}, + {"0S)KVU", 'F'}, + {"0S)O((", 'F'}, + {"0S)O(1", 'F'}, + {"0S)O(E", 'F'}, + {"0S)O(F", 'F'}, + {"0S)O(N", 'F'}, + {"0S)O(S", 'F'}, + {"0S)O(V", 'F'}, + {"0S)O1", 'F'}, + {"0S)O1&", 'F'}, + {"0S)O1)", 'F'}, + {"0S)O1;", 'F'}, + {"0S)O1B", 'F'}, + {"0S)O1C", 'F'}, + {"0S)O1K", 'F'}, + {"0S)O1O", 'F'}, + {"0S)O1U", 'F'}, + {"0S)OF(", 'F'}, + {"0S)ON", 'F'}, + {"0S)ON&", 'F'}, + {"0S)ON)", 'F'}, + {"0S)ON;", 'F'}, + {"0S)ONB", 'F'}, + {"0S)ONC", 'F'}, + {"0S)ONK", 'F'}, + {"0S)ONO", 'F'}, + {"0S)ONU", 'F'}, + {"0S)OS", 'F'}, + {"0S)OS&", 'F'}, + {"0S)OS)", 'F'}, + {"0S)OS;", 'F'}, + {"0S)OSB", 'F'}, + {"0S)OSC", 'F'}, + {"0S)OSK", 'F'}, + {"0S)OSO", 'F'}, + {"0S)OSU", 'F'}, + {"0S)OV", 'F'}, + {"0S)OV&", 'F'}, + {"0S)OV)", 'F'}, + {"0S)OV;", 'F'}, + {"0S)OVB", 'F'}, + {"0S)OVC", 'F'}, + {"0S)OVK", 'F'}, + {"0S)OVO", 'F'}, + {"0S)OVU", 'F'}, + {"0S)U((", 'F'}, + {"0S)U(E", 'F'}, + {"0S)UE(", 'F'}, + {"0S)UE1", 'F'}, + {"0S)UEF", 'F'}, + {"0S)UEK", 'F'}, + {"0S)UEN", 'F'}, + {"0S)UES", 'F'}, + {"0S)UEV", 'F'}, + {"0S,(((", 'F'}, + {"0S,((1", 'F'}, + {"0S,((E", 'F'}, + {"0S,((F", 'F'}, + {"0S,((N", 'F'}, + {"0S,((S", 'F'}, + {"0S,((V", 'F'}, + {"0S,(1)", 'F'}, + {"0S,(1O", 'F'}, + {"0S,(E(", 'F'}, + {"0S,(E1", 'F'}, + {"0S,(EF", 'F'}, + {"0S,(EK", 'F'}, + {"0S,(EN", 'F'}, + {"0S,(ES", 'F'}, + {"0S,(EV", 'F'}, + {"0S,(F(", 'F'}, + {"0S,(N)", 'F'}, + {"0S,(NO", 'F'}, + {"0S,(S)", 'F'}, + {"0S,(SO", 'F'}, + {"0S,(V)", 'F'}, + {"0S,(VO", 'F'}, + {"0S,F((", 'F'}, + {"0S,F()", 'F'}, + {"0S,F(1", 'F'}, + {"0S,F(F", 'F'}, + {"0S,F(N", 'F'}, + {"0S,F(S", 'F'}, + {"0S,F(T", 'F'}, + {"0S,F(V", 'F'}, + {"0S,V))", 'F'}, + {"0S,V),", 'F'}, + {"0S,V)O", 'F'}, + {"0S,VB(", 'F'}, + {"0S,VB1", 'F'}, + {"0S,VBF", 'F'}, + {"0S,VBN", 'F'}, + {"0S,VBS", 'F'}, + {"0S,VBV", 'F'}, + {"0S,VO(", 'F'}, + {"0S,VOF", 'F'}, + {"0S,VOS", 'F'}, + {"0S,VUE", 'F'}, + {"0S1F((", 'F'}, + {"0S1F()", 'F'}, + {"0S1F(1", 'F'}, + {"0S1F(F", 'F'}, + {"0S1F(N", 'F'}, + {"0S1F(S", 'F'}, + {"0S1F(V", 'F'}, + {"0S1NC", 'F'}, + {"0S1NO(", 'F'}, + {"0S1NOF", 'F'}, + {"0S1NOS", 'F'}, + {"0S1NOV", 'F'}, + {"0S1O((", 'F'}, + {"0S1O(1", 'F'}, + {"0S1O(F", 'F'}, + {"0S1O(N", 'F'}, + {"0S1O(S", 'F'}, + {"0S1O(V", 'F'}, + {"0S1OF(", 'F'}, + {"0S1OS(", 'F'}, + {"0S1OS1", 'F'}, + {"0S1OSF", 'F'}, + {"0S1OSO", 'F'}, + {"0S1OSU", 'F'}, + {"0S1OSV", 'F'}, + {"0S1OV(", 'F'}, + {"0S1OVF", 'F'}, + {"0S1OVO", 'F'}, + {"0S1OVS", 'F'}, + {"0S1OVU", 'F'}, + {"0S1S;", 'F'}, + {"0S1S;C", 'F'}, + {"0S1SC", 'F'}, + {"0S1UE", 'F'}, + {"0S1UE;", 'F'}, + {"0S1UEC", 'F'}, + {"0S1UEK", 'F'}, + {"0S1V", 'F'}, + {"0S1V;", 'F'}, + {"0S1V;C", 'F'}, + {"0S1VC", 'F'}, + {"0S1VO(", 'F'}, + {"0S1VOF", 'F'}, + {"0S1VOS", 'F'}, + {"0S;E((", 'F'}, + {"0S;E(1", 'F'}, + {"0S;E(E", 'F'}, + {"0S;E(F", 'F'}, + {"0S;E(N", 'F'}, + {"0S;E(S", 'F'}, + {"0S;E(V", 'F'}, + {"0S;E1,", 'F'}, + {"0S;E1;", 'F'}, + {"0S;E1C", 'F'}, + {"0S;E1O", 'F'}, + {"0S;E1T", 'F'}, + {"0S;EF(", 'F'}, + {"0S;EK(", 'F'}, + {"0S;EK1", 'F'}, + {"0S;EKF", 'F'}, + {"0S;EKN", 'F'}, + {"0S;EKO", 'F'}, + {"0S;EKS", 'F'}, + {"0S;EKV", 'F'}, + {"0S;EN,", 'F'}, + {"0S;EN;", 'F'}, + {"0S;ENC", 'F'}, + {"0S;ENK", 'F'}, + {"0S;ENO", 'F'}, + {"0S;ENT", 'F'}, + {"0S;EO(", 'F'}, + {"0S;ES,", 'F'}, + {"0S;ES;", 'F'}, + {"0S;ESC", 'F'}, + {"0S;ESO", 'F'}, + {"0S;EST", 'F'}, + {"0S;EV,", 'F'}, + {"0S;EV;", 'F'}, + {"0S;EVC", 'F'}, + {"0S;EVO", 'F'}, + {"0S;EVT", 'F'}, + {"0S;N:T", 'F'}, + {"0S;T((", 'F'}, + {"0S;T(1", 'F'}, + {"0S;T(E", 'F'}, + {"0S;T(F", 'F'}, + {"0S;T(N", 'F'}, + {"0S;T(S", 'F'}, + {"0S;T(V", 'F'}, + {"0S;T1,", 'F'}, + {"0S;T1;", 'F'}, + {"0S;T1C", 'F'}, + {"0S;T1F", 'F'}, + {"0S;T1O", 'F'}, + {"0S;T1T", 'F'}, + {"0S;T;", 'F'}, + {"0S;T;C", 'F'}, + {"0S;TF(", 'F'}, + {"0S;TK(", 'F'}, + {"0S;TK1", 'F'}, + {"0S;TKF", 'F'}, + {"0S;TKK", 'F'}, + {"0S;TKN", 'F'}, + {"0S;TKO", 'F'}, + {"0S;TKS", 'F'}, + {"0S;TKV", 'F'}, + {"0S;TN(", 'F'}, + {"0S;TN,", 'F'}, + {"0S;TN1", 'F'}, + {"0S;TN;", 'F'}, + {"0S;TNC", 'F'}, + {"0S;TNE", 'F'}, + {"0S;TNF", 'F'}, + {"0S;TNK", 'F'}, + {"0S;TNN", 'F'}, + {"0S;TNO", 'F'}, + {"0S;TNS", 'F'}, + {"0S;TNT", 'F'}, + {"0S;TNV", 'F'}, + {"0S;TO(", 'F'}, + {"0S;TS,", 'F'}, + {"0S;TS;", 'F'}, + {"0S;TSC", 'F'}, + {"0S;TSF", 'F'}, + {"0S;TSO", 'F'}, + {"0S;TST", 'F'}, + {"0S;TT(", 'F'}, + {"0S;TT1", 'F'}, + {"0S;TTF", 'F'}, + {"0S;TTN", 'F'}, + {"0S;TTS", 'F'}, + {"0S;TTV", 'F'}, + {"0S;TV,", 'F'}, + {"0S;TV;", 'F'}, + {"0S;TVC", 'F'}, + {"0S;TVF", 'F'}, + {"0S;TVO", 'F'}, + {"0S;TVT", 'F'}, + {"0SA(((", 'F'}, + {"0SA((1", 'F'}, + {"0SA((F", 'F'}, + {"0SA((N", 'F'}, + {"0SA((S", 'F'}, + {"0SA((V", 'F'}, + {"0SA(F(", 'F'}, + {"0SA(N)", 'F'}, + {"0SA(NO", 'F'}, + {"0SA(S)", 'F'}, + {"0SA(SO", 'F'}, + {"0SA(V)", 'F'}, + {"0SA(VO", 'F'}, + {"0SAF((", 'F'}, + {"0SAF()", 'F'}, + {"0SAF(1", 'F'}, + {"0SAF(F", 'F'}, + {"0SAF(N", 'F'}, + {"0SAF(S", 'F'}, + {"0SAF(V", 'F'}, + {"0SASO(", 'F'}, + {"0SASO1", 'F'}, + {"0SASOF", 'F'}, + {"0SASON", 'F'}, + {"0SASOS", 'F'}, + {"0SASOV", 'F'}, + {"0SASUE", 'F'}, + {"0SATO(", 'F'}, + {"0SATO1", 'F'}, + {"0SATOF", 'F'}, + {"0SATON", 'F'}, + {"0SATOS", 'F'}, + {"0SATOV", 'F'}, + {"0SATUE", 'F'}, + {"0SAVO(", 'F'}, + {"0SAVOF", 'F'}, + {"0SAVOS", 'F'}, + {"0SAVUE", 'F'}, + {"0SB(((", 'F'}, + {"0SB((1", 'F'}, + {"0SB((F", 'F'}, + {"0SB((N", 'F'}, + {"0SB((S", 'F'}, + {"0SB((V", 'F'}, + {"0SB(1)", 'F'}, + {"0SB(1O", 'F'}, + {"0SB(F(", 'F'}, + {"0SB(N)", 'F'}, + {"0SB(NO", 'F'}, + {"0SB(S)", 'F'}, + {"0SB(SO", 'F'}, + {"0SB(V)", 'F'}, + {"0SB(VO", 'F'}, + {"0SB1", 'F'}, + {"0SB1&(", 'F'}, + {"0SB1&1", 'F'}, + {"0SB1&F", 'F'}, + {"0SB1&N", 'F'}, + {"0SB1&S", 'F'}, + {"0SB1&V", 'F'}, + {"0SB1,(", 'F'}, + {"0SB1,F", 'F'}, + {"0SB1,V", 'F'}, + {"0SB1;", 'F'}, + {"0SB1;C", 'F'}, + {"0SB1B(", 'F'}, + {"0SB1B1", 'F'}, + {"0SB1BF", 'F'}, + {"0SB1BN", 'F'}, + {"0SB1BS", 'F'}, + {"0SB1BV", 'F'}, + {"0SB1C", 'F'}, + {"0SB1K(", 'F'}, + {"0SB1K1", 'F'}, + {"0SB1KF", 'F'}, + {"0SB1KN", 'F'}, + {"0SB1KS", 'F'}, + {"0SB1KV", 'F'}, + {"0SB1O(", 'F'}, + {"0SB1OF", 'F'}, + {"0SB1OS", 'F'}, + {"0SB1OV", 'F'}, + {"0SB1U(", 'F'}, + {"0SB1UE", 'F'}, + {"0SBE((", 'F'}, + {"0SBE(1", 'F'}, + {"0SBE(F", 'F'}, + {"0SBE(N", 'F'}, + {"0SBE(S", 'F'}, + {"0SBE(V", 'F'}, + {"0SBEK(", 'F'}, + {"0SBF((", 'F'}, + {"0SBF()", 'F'}, + {"0SBF(1", 'F'}, + {"0SBF(F", 'F'}, + {"0SBF(N", 'F'}, + {"0SBF(S", 'F'}, + {"0SBF(V", 'F'}, + {"0SBN", 'F'}, + {"0SBN&(", 'F'}, + {"0SBN&1", 'F'}, + {"0SBN&F", 'F'}, + {"0SBN&N", 'F'}, + {"0SBN&S", 'F'}, + {"0SBN&V", 'F'}, + {"0SBN,(", 'F'}, + {"0SBN,F", 'F'}, + {"0SBN,V", 'F'}, + {"0SBN;", 'F'}, + {"0SBN;C", 'F'}, + {"0SBNB(", 'F'}, + {"0SBNB1", 'F'}, + {"0SBNBF", 'F'}, + {"0SBNBN", 'F'}, + {"0SBNBS", 'F'}, + {"0SBNBV", 'F'}, + {"0SBNC", 'F'}, + {"0SBNK(", 'F'}, + {"0SBNK1", 'F'}, + {"0SBNKF", 'F'}, + {"0SBNKN", 'F'}, + {"0SBNKS", 'F'}, + {"0SBNKV", 'F'}, + {"0SBNO(", 'F'}, + {"0SBNOF", 'F'}, + {"0SBNOS", 'F'}, + {"0SBNOV", 'F'}, + {"0SBNU(", 'F'}, + {"0SBNUE", 'F'}, + {"0SBS", 'F'}, + {"0SBS&(", 'F'}, + {"0SBS&1", 'F'}, + {"0SBS&F", 'F'}, + {"0SBS&N", 'F'}, + {"0SBS&S", 'F'}, + {"0SBS&V", 'F'}, + {"0SBS,(", 'F'}, + {"0SBS,F", 'F'}, + {"0SBS,V", 'F'}, + {"0SBS;", 'F'}, + {"0SBS;C", 'F'}, + {"0SBSB(", 'F'}, + {"0SBSB1", 'F'}, + {"0SBSBF", 'F'}, + {"0SBSBN", 'F'}, + {"0SBSBS", 'F'}, + {"0SBSBV", 'F'}, + {"0SBSC", 'F'}, + {"0SBSK(", 'F'}, + {"0SBSK1", 'F'}, + {"0SBSKF", 'F'}, + {"0SBSKN", 'F'}, + {"0SBSKS", 'F'}, + {"0SBSKV", 'F'}, + {"0SBSO(", 'F'}, + {"0SBSO1", 'F'}, + {"0SBSOF", 'F'}, + {"0SBSON", 'F'}, + {"0SBSOS", 'F'}, + {"0SBSOV", 'F'}, + {"0SBSU(", 'F'}, + {"0SBSUE", 'F'}, + {"0SBV", 'F'}, + {"0SBV&(", 'F'}, + {"0SBV&1", 'F'}, + {"0SBV&F", 'F'}, + {"0SBV&N", 'F'}, + {"0SBV&S", 'F'}, + {"0SBV&V", 'F'}, + {"0SBV,(", 'F'}, + {"0SBV,1", 'F'}, + {"0SBV,F", 'F'}, + {"0SBV,N", 'F'}, + {"0SBV,S", 'F'}, + {"0SBV,V", 'F'}, + {"0SBV;", 'F'}, + {"0SBV;C", 'F'}, + {"0SBVB(", 'F'}, + {"0SBVB1", 'F'}, + {"0SBVBF", 'F'}, + {"0SBVBN", 'F'}, + {"0SBVBS", 'F'}, + {"0SBVBV", 'F'}, + {"0SBVC", 'F'}, + {"0SBVK(", 'F'}, + {"0SBVK1", 'F'}, + {"0SBVKF", 'F'}, + {"0SBVKN", 'F'}, + {"0SBVKS", 'F'}, + {"0SBVKV", 'F'}, + {"0SBVO(", 'F'}, + {"0SBVOF", 'F'}, + {"0SBVOS", 'F'}, + {"0SBVU(", 'F'}, + {"0SBVUE", 'F'}, + {"0SC", 'F'}, + {"0SE(((", 'F'}, + {"0SE((1", 'F'}, + {"0SE((F", 'F'}, + {"0SE((N", 'F'}, + {"0SE((S", 'F'}, + {"0SE((V", 'F'}, + {"0SE(1)", 'F'}, + {"0SE(1O", 'F'}, + {"0SE(F(", 'F'}, + {"0SE(N)", 'F'}, + {"0SE(NO", 'F'}, + {"0SE(S)", 'F'}, + {"0SE(SO", 'F'}, + {"0SE(V)", 'F'}, + {"0SE(VO", 'F'}, + {"0SE1C", 'F'}, + {"0SE1O(", 'F'}, + {"0SE1OF", 'F'}, + {"0SE1OS", 'F'}, + {"0SE1OV", 'F'}, + {"0SE1UE", 'F'}, + {"0SEF((", 'F'}, + {"0SEF()", 'F'}, + {"0SEF(1", 'F'}, + {"0SEF(F", 'F'}, + {"0SEF(N", 'F'}, + {"0SEF(S", 'F'}, + {"0SEF(V", 'F'}, + {"0SEK((", 'F'}, + {"0SEK(1", 'F'}, + {"0SEK(E", 'F'}, + {"0SEK(F", 'F'}, + {"0SEK(N", 'F'}, + {"0SEK(S", 'F'}, + {"0SEK(V", 'F'}, + {"0SEK1C", 'F'}, + {"0SEK1O", 'F'}, + {"0SEK1U", 'F'}, + {"0SEKF(", 'F'}, + {"0SEKNC", 'F'}, + {"0SEKNE", 'F'}, + {"0SEKNU", 'F'}, + {"0SEKOK", 'F'}, + {"0SEKSC", 'F'}, + {"0SEKSO", 'F'}, + {"0SEKSU", 'F'}, + {"0SEKU(", 'F'}, + {"0SEKU1", 'F'}, + {"0SEKUE", 'F'}, + {"0SEKUF", 'F'}, + {"0SEKUN", 'F'}, + {"0SEKUS", 'F'}, + {"0SEKUV", 'F'}, + {"0SEKVC", 'F'}, + {"0SEKVO", 'F'}, + {"0SEKVU", 'F'}, + {"0SENC", 'F'}, + {"0SENEN", 'F'}, + {"0SENO(", 'F'}, + {"0SENOF", 'F'}, + {"0SENOS", 'F'}, + {"0SENOV", 'F'}, + {"0SENUE", 'F'}, + {"0SEOKN", 'F'}, + {"0SESC", 'F'}, + {"0SESO(", 'F'}, + {"0SESO1", 'F'}, + {"0SESOF", 'F'}, + {"0SESON", 'F'}, + {"0SESOS", 'F'}, + {"0SESOV", 'F'}, + {"0SESUE", 'F'}, + {"0SEU((", 'F'}, + {"0SEU(1", 'F'}, + {"0SEU(F", 'F'}, + {"0SEU(N", 'F'}, + {"0SEU(S", 'F'}, + {"0SEU(V", 'F'}, + {"0SEU1,", 'F'}, + {"0SEU1C", 'F'}, + {"0SEU1O", 'F'}, + {"0SEUEF", 'F'}, + {"0SEUEK", 'F'}, + {"0SEUF(", 'F'}, + {"0SEUN,", 'F'}, + {"0SEUNC", 'F'}, + {"0SEUNO", 'F'}, + {"0SEUS,", 'F'}, + {"0SEUSC", 'F'}, + {"0SEUSO", 'F'}, + {"0SEUV,", 'F'}, + {"0SEUVC", 'F'}, + {"0SEUVO", 'F'}, + {"0SEVC", 'F'}, + {"0SEVO(", 'F'}, + {"0SEVOF", 'F'}, + {"0SEVOS", 'F'}, + {"0SEVUE", 'F'}, + {"0SF(((", 'F'}, + {"0SF(()", 'F'}, + {"0SF((1", 'F'}, + {"0SF((F", 'F'}, + {"0SF((N", 'F'}, + {"0SF((S", 'F'}, + {"0SF((V", 'F'}, + {"0SF())", 'F'}, + {"0SF()1", 'F'}, + {"0SF()F", 'F'}, + {"0SF()K", 'F'}, + {"0SF()N", 'F'}, + {"0SF()O", 'F'}, + {"0SF()S", 'F'}, + {"0SF()U", 'F'}, + {"0SF()V", 'F'}, + {"0SF(1)", 'F'}, + {"0SF(1N", 'F'}, + {"0SF(1O", 'F'}, + {"0SF(F(", 'F'}, + {"0SF(N)", 'F'}, + {"0SF(N,", 'F'}, + {"0SF(NO", 'F'}, + {"0SF(S)", 'F'}, + {"0SF(SO", 'F'}, + {"0SF(V)", 'F'}, + {"0SF(VO", 'F'}, + {"0SK(((", 'F'}, + {"0SK((1", 'F'}, + {"0SK((F", 'F'}, + {"0SK((N", 'F'}, + {"0SK((S", 'F'}, + {"0SK((V", 'F'}, + {"0SK(1)", 'F'}, + {"0SK(1O", 'F'}, + {"0SK(F(", 'F'}, + {"0SK(N)", 'F'}, + {"0SK(NO", 'F'}, + {"0SK(S)", 'F'}, + {"0SK(SO", 'F'}, + {"0SK(V)", 'F'}, + {"0SK(VO", 'F'}, + {"0SK)&(", 'F'}, + {"0SK)&1", 'F'}, + {"0SK)&F", 'F'}, + {"0SK)&N", 'F'}, + {"0SK)&S", 'F'}, + {"0SK)&V", 'F'}, + {"0SK))&", 'F'}, + {"0SK)))", 'F'}, + {"0SK));", 'F'}, + {"0SK))B", 'F'}, + {"0SK))E", 'F'}, + {"0SK))K", 'F'}, + {"0SK))O", 'F'}, + {"0SK))U", 'F'}, + {"0SK);E", 'F'}, + {"0SK);T", 'F'}, + {"0SK)B(", 'F'}, + {"0SK)B1", 'F'}, + {"0SK)BF", 'F'}, + {"0SK)BN", 'F'}, + {"0SK)BS", 'F'}, + {"0SK)BV", 'F'}, + {"0SK)E(", 'F'}, + {"0SK)E1", 'F'}, + {"0SK)EF", 'F'}, + {"0SK)EK", 'F'}, + {"0SK)EN", 'F'}, + {"0SK)ES", 'F'}, + {"0SK)EV", 'F'}, + {"0SK)OF", 'F'}, + {"0SK)UE", 'F'}, + {"0SK1", 'F'}, + {"0SK1&(", 'F'}, + {"0SK1&1", 'F'}, + {"0SK1&F", 'F'}, + {"0SK1&N", 'F'}, + {"0SK1&S", 'F'}, + {"0SK1&V", 'F'}, + {"0SK1;", 'F'}, + {"0SK1;C", 'F'}, + {"0SK1;E", 'F'}, + {"0SK1;T", 'F'}, + {"0SK1B(", 'F'}, + {"0SK1B1", 'F'}, + {"0SK1BF", 'F'}, + {"0SK1BN", 'F'}, + {"0SK1BS", 'F'}, + {"0SK1BV", 'F'}, + {"0SK1C", 'F'}, + {"0SK1E(", 'F'}, + {"0SK1E1", 'F'}, + {"0SK1EF", 'F'}, + {"0SK1EK", 'F'}, + {"0SK1EN", 'F'}, + {"0SK1ES", 'F'}, + {"0SK1EV", 'F'}, + {"0SK1O(", 'F'}, + {"0SK1OF", 'F'}, + {"0SK1OS", 'F'}, + {"0SK1OV", 'F'}, + {"0SK1U(", 'F'}, + {"0SK1UE", 'F'}, + {"0SKF((", 'F'}, + {"0SKF()", 'F'}, + {"0SKF(1", 'F'}, + {"0SKF(F", 'F'}, + {"0SKF(N", 'F'}, + {"0SKF(S", 'F'}, + {"0SKF(V", 'F'}, + {"0SKN", 'F'}, + {"0SKN&(", 'F'}, + {"0SKN&1", 'F'}, + {"0SKN&F", 'F'}, + {"0SKN&N", 'F'}, + {"0SKN&S", 'F'}, + {"0SKN&V", 'F'}, + {"0SKN;", 'F'}, + {"0SKN;C", 'F'}, + {"0SKN;E", 'F'}, + {"0SKN;T", 'F'}, + {"0SKNB(", 'F'}, + {"0SKNB1", 'F'}, + {"0SKNBF", 'F'}, + {"0SKNBN", 'F'}, + {"0SKNBS", 'F'}, + {"0SKNBV", 'F'}, + {"0SKNC", 'F'}, + {"0SKNE(", 'F'}, + {"0SKNE1", 'F'}, + {"0SKNEF", 'F'}, + {"0SKNEN", 'F'}, + {"0SKNES", 'F'}, + {"0SKNEV", 'F'}, + {"0SKNU(", 'F'}, + {"0SKNUE", 'F'}, + {"0SKS", 'F'}, + {"0SKS&(", 'F'}, + {"0SKS&1", 'F'}, + {"0SKS&F", 'F'}, + {"0SKS&N", 'F'}, + {"0SKS&S", 'F'}, + {"0SKS&V", 'F'}, + {"0SKS;", 'F'}, + {"0SKS;C", 'F'}, + {"0SKS;E", 'F'}, + {"0SKS;T", 'F'}, + {"0SKSB(", 'F'}, + {"0SKSB1", 'F'}, + {"0SKSBF", 'F'}, + {"0SKSBN", 'F'}, + {"0SKSBS", 'F'}, + {"0SKSBV", 'F'}, + {"0SKSC", 'F'}, + {"0SKSE(", 'F'}, + {"0SKSE1", 'F'}, + {"0SKSEF", 'F'}, + {"0SKSEK", 'F'}, + {"0SKSEN", 'F'}, + {"0SKSES", 'F'}, + {"0SKSEV", 'F'}, + {"0SKSO(", 'F'}, + {"0SKSO1", 'F'}, + {"0SKSOF", 'F'}, + {"0SKSON", 'F'}, + {"0SKSOS", 'F'}, + {"0SKSOV", 'F'}, + {"0SKSU(", 'F'}, + {"0SKSUE", 'F'}, + {"0SKUE(", 'F'}, + {"0SKUE1", 'F'}, + {"0SKUEF", 'F'}, + {"0SKUEK", 'F'}, + {"0SKUEN", 'F'}, + {"0SKUES", 'F'}, + {"0SKUEV", 'F'}, + {"0SKV", 'F'}, + {"0SKV&(", 'F'}, + {"0SKV&1", 'F'}, + {"0SKV&F", 'F'}, + {"0SKV&N", 'F'}, + {"0SKV&S", 'F'}, + {"0SKV&V", 'F'}, + {"0SKV;", 'F'}, + {"0SKV;C", 'F'}, + {"0SKV;E", 'F'}, + {"0SKV;T", 'F'}, + {"0SKVB(", 'F'}, + {"0SKVB1", 'F'}, + {"0SKVBF", 'F'}, + {"0SKVBN", 'F'}, + {"0SKVBS", 'F'}, + {"0SKVBV", 'F'}, + {"0SKVC", 'F'}, + {"0SKVE(", 'F'}, + {"0SKVE1", 'F'}, + {"0SKVEF", 'F'}, + {"0SKVEK", 'F'}, + {"0SKVEN", 'F'}, + {"0SKVES", 'F'}, + {"0SKVEV", 'F'}, + {"0SKVO(", 'F'}, + {"0SKVOF", 'F'}, + {"0SKVOS", 'F'}, + {"0SKVU(", 'F'}, + {"0SKVUE", 'F'}, + {"0SO(((", 'F'}, + {"0SO((1", 'F'}, + {"0SO((E", 'F'}, + {"0SO((F", 'F'}, + {"0SO((N", 'F'}, + {"0SO((O", 'F'}, + {"0SO((S", 'F'}, + {"0SO((T", 'F'}, + {"0SO((V", 'F'}, + {"0SO(1&", 'F'}, + {"0SO(1)", 'F'}, + {"0SO(1,", 'F'}, + {"0SO(1O", 'F'}, + {"0SO(E(", 'F'}, + {"0SO(E1", 'F'}, + {"0SO(EE", 'F'}, + {"0SO(EF", 'F'}, + {"0SO(EK", 'F'}, + {"0SO(EN", 'F'}, + {"0SO(ES", 'F'}, + {"0SO(EV", 'F'}, + {"0SO(F(", 'F'}, + {"0SO(N&", 'F'}, + {"0SO(N)", 'F'}, + {"0SO(N,", 'F'}, + {"0SO(NO", 'F'}, + {"0SO(O(", 'F'}, + {"0SO(O1", 'F'}, + {"0SO(OF", 'F'}, + {"0SO(ON", 'F'}, + {"0SO(OS", 'F'}, + {"0SO(OV", 'F'}, + {"0SO(S&", 'F'}, + {"0SO(S)", 'F'}, + {"0SO(S,", 'F'}, + {"0SO(SO", 'F'}, + {"0SO(T(", 'F'}, + {"0SO(V&", 'F'}, + {"0SO(V)", 'F'}, + {"0SO(V,", 'F'}, + {"0SO(VO", 'F'}, + {"0SO1&(", 'F'}, + {"0SO1&1", 'F'}, + {"0SO1&E", 'F'}, + {"0SO1&F", 'F'}, + {"0SO1&K", 'F'}, + {"0SO1&N", 'F'}, + {"0SO1&S", 'F'}, + {"0SO1&U", 'F'}, + {"0SO1&V", 'F'}, + {"0SO1((", 'F'}, + {"0SO1(E", 'F'}, + {"0SO1(U", 'F'}, + {"0SO1)&", 'F'}, + {"0SO1))", 'F'}, + {"0SO1),", 'F'}, + {"0SO1);", 'F'}, + {"0SO1)B", 'F'}, + {"0SO1)E", 'F'}, + {"0SO1)K", 'F'}, + {"0SO1)O", 'F'}, + {"0SO1)U", 'F'}, + {"0SO1,(", 'F'}, + {"0SO1,F", 'F'}, + {"0SO1,V", 'F'}, + {"0SO1;", 'F'}, + {"0SO1;C", 'F'}, + {"0SO1;E", 'F'}, + {"0SO1;N", 'F'}, + {"0SO1;T", 'F'}, + {"0SO1A(", 'F'}, + {"0SO1AF", 'F'}, + {"0SO1AS", 'F'}, + {"0SO1AT", 'F'}, + {"0SO1AV", 'F'}, + {"0SO1B(", 'F'}, + {"0SO1B1", 'F'}, + {"0SO1BE", 'F'}, + {"0SO1BF", 'F'}, + {"0SO1BN", 'F'}, + {"0SO1BS", 'F'}, + {"0SO1BV", 'F'}, + {"0SO1C", 'F'}, + {"0SO1E(", 'F'}, + {"0SO1E1", 'F'}, + {"0SO1EF", 'F'}, + {"0SO1EK", 'F'}, + {"0SO1EN", 'F'}, + {"0SO1EO", 'F'}, + {"0SO1ES", 'F'}, + {"0SO1EU", 'F'}, + {"0SO1EV", 'F'}, + {"0SO1F(", 'F'}, + {"0SO1K(", 'F'}, + {"0SO1K)", 'F'}, + {"0SO1K1", 'F'}, + {"0SO1KB", 'F'}, + {"0SO1KF", 'F'}, + {"0SO1KN", 'F'}, + {"0SO1KS", 'F'}, + {"0SO1KU", 'F'}, + {"0SO1KV", 'F'}, + {"0SO1N&", 'F'}, + {"0SO1N(", 'F'}, + {"0SO1N,", 'F'}, + {"0SO1NE", 'F'}, + {"0SO1NF", 'F'}, + {"0SO1NO", 'F'}, + {"0SO1NU", 'F'}, + {"0SO1O(", 'F'}, + {"0SO1OF", 'F'}, + {"0SO1OK", 'F'}, + {"0SO1OS", 'F'}, + {"0SO1OT", 'F'}, + {"0SO1OU", 'F'}, + {"0SO1OV", 'F'}, + {"0SO1S(", 'F'}, + {"0SO1SF", 'F'}, + {"0SO1SU", 'F'}, + {"0SO1SV", 'F'}, + {"0SO1U", 'F'}, + {"0SO1U(", 'F'}, + {"0SO1U1", 'F'}, + {"0SO1U;", 'F'}, + {"0SO1UC", 'F'}, + {"0SO1UE", 'F'}, + {"0SO1UF", 'F'}, + {"0SO1UK", 'F'}, + {"0SO1UN", 'F'}, + {"0SO1UO", 'F'}, + {"0SO1US", 'F'}, + {"0SO1UT", 'F'}, + {"0SO1UV", 'F'}, + {"0SO1V(", 'F'}, + {"0SO1VF", 'F'}, + {"0SO1VO", 'F'}, + {"0SO1VS", 'F'}, + {"0SO1VU", 'F'}, + {"0SOF((", 'F'}, + {"0SOF()", 'F'}, + {"0SOF(1", 'F'}, + {"0SOF(E", 'F'}, + {"0SOF(F", 'F'}, + {"0SOF(N", 'F'}, + {"0SOF(S", 'F'}, + {"0SOF(V", 'F'}, + {"0SOK&(", 'F'}, + {"0SOK&1", 'F'}, + {"0SOK&F", 'F'}, + {"0SOK&N", 'F'}, + {"0SOK&S", 'F'}, + {"0SOK&V", 'F'}, + {"0SOK((", 'F'}, + {"0SOK(1", 'F'}, + {"0SOK(F", 'F'}, + {"0SOK(N", 'F'}, + {"0SOK(S", 'F'}, + {"0SOK(V", 'F'}, + {"0SOK1C", 'F'}, + {"0SOK1O", 'F'}, + {"0SOKF(", 'F'}, + {"0SOKNC", 'F'}, + {"0SOKO(", 'F'}, + {"0SOKO1", 'F'}, + {"0SOKOF", 'F'}, + {"0SOKON", 'F'}, + {"0SOKOS", 'F'}, + {"0SOKOV", 'F'}, + {"0SOKSC", 'F'}, + {"0SOKSO", 'F'}, + {"0SOKVC", 'F'}, + {"0SOKVO", 'F'}, + {"0SON&(", 'F'}, + {"0SON&1", 'F'}, + {"0SON&E", 'F'}, + {"0SON&F", 'F'}, + {"0SON&K", 'F'}, + {"0SON&N", 'F'}, + {"0SON&S", 'F'}, + {"0SON&U", 'F'}, + {"0SON&V", 'F'}, + {"0SON((", 'F'}, + {"0SON(1", 'F'}, + {"0SON(E", 'F'}, + {"0SON(F", 'F'}, + {"0SON(S", 'F'}, + {"0SON(U", 'F'}, + {"0SON(V", 'F'}, + {"0SON)&", 'F'}, + {"0SON))", 'F'}, + {"0SON),", 'F'}, + {"0SON);", 'F'}, + {"0SON)B", 'F'}, + {"0SON)E", 'F'}, + {"0SON)K", 'F'}, + {"0SON)O", 'F'}, + {"0SON)U", 'F'}, + {"0SON,(", 'F'}, + {"0SON,F", 'F'}, + {"0SON,V", 'F'}, + {"0SON1(", 'F'}, + {"0SON1F", 'F'}, + {"0SON1N", 'F'}, + {"0SON1O", 'F'}, + {"0SON1S", 'F'}, + {"0SON1U", 'F'}, + {"0SON1V", 'F'}, + {"0SON;", 'F'}, + {"0SON;C", 'F'}, + {"0SON;E", 'F'}, + {"0SON;N", 'F'}, + {"0SON;T", 'F'}, + {"0SONA(", 'F'}, + {"0SONAF", 'F'}, + {"0SONAS", 'F'}, + {"0SONAT", 'F'}, + {"0SONAV", 'F'}, + {"0SONB(", 'F'}, + {"0SONB1", 'F'}, + {"0SONBE", 'F'}, + {"0SONBF", 'F'}, + {"0SONBN", 'F'}, + {"0SONBS", 'F'}, + {"0SONBV", 'F'}, + {"0SONE(", 'F'}, + {"0SONE1", 'F'}, + {"0SONEF", 'F'}, + {"0SONEN", 'F'}, + {"0SONEO", 'F'}, + {"0SONES", 'F'}, + {"0SONEU", 'F'}, + {"0SONEV", 'F'}, + {"0SONF(", 'F'}, + {"0SONK(", 'F'}, + {"0SONK)", 'F'}, + {"0SONK1", 'F'}, + {"0SONKB", 'F'}, + {"0SONKF", 'F'}, + {"0SONKS", 'F'}, + {"0SONKU", 'F'}, + {"0SONKV", 'F'}, + {"0SONO(", 'F'}, + {"0SONOF", 'F'}, + {"0SONOK", 'F'}, + {"0SONOS", 'F'}, + {"0SONOT", 'F'}, + {"0SONOU", 'F'}, + {"0SONOV", 'F'}, + {"0SONSU", 'F'}, + {"0SONU", 'F'}, + {"0SONU(", 'F'}, + {"0SONU1", 'F'}, + {"0SONU;", 'F'}, + {"0SONUC", 'F'}, + {"0SONUE", 'F'}, + {"0SONUF", 'F'}, + {"0SONUK", 'F'}, + {"0SONUN", 'F'}, + {"0SONUO", 'F'}, + {"0SONUS", 'F'}, + {"0SONUT", 'F'}, + {"0SONUV", 'F'}, + {"0SOS", 'F'}, + {"0SOS&(", 'F'}, + {"0SOS&1", 'F'}, + {"0SOS&E", 'F'}, + {"0SOS&F", 'F'}, + {"0SOS&K", 'F'}, + {"0SOS&N", 'F'}, + {"0SOS&S", 'F'}, + {"0SOS&U", 'F'}, + {"0SOS&V", 'F'}, + {"0SOS((", 'F'}, + {"0SOS(E", 'F'}, + {"0SOS(U", 'F'}, + {"0SOS)&", 'F'}, + {"0SOS))", 'F'}, + {"0SOS),", 'F'}, + {"0SOS);", 'F'}, + {"0SOS)B", 'F'}, + {"0SOS)E", 'F'}, + {"0SOS)K", 'F'}, + {"0SOS)O", 'F'}, + {"0SOS)U", 'F'}, + {"0SOS,(", 'F'}, + {"0SOS,F", 'F'}, + {"0SOS,V", 'F'}, + {"0SOS1(", 'F'}, + {"0SOS1F", 'F'}, + {"0SOS1N", 'F'}, + {"0SOS1O", 'F'}, + {"0SOS1S", 'F'}, + {"0SOS1U", 'F'}, + {"0SOS1V", 'F'}, + {"0SOS;", 'F'}, + {"0SOS;C", 'F'}, + {"0SOS;E", 'F'}, + {"0SOS;N", 'F'}, + {"0SOS;T", 'F'}, + {"0SOSA(", 'F'}, + {"0SOSAF", 'F'}, + {"0SOSAS", 'F'}, + {"0SOSAT", 'F'}, + {"0SOSAV", 'F'}, + {"0SOSB(", 'F'}, + {"0SOSB1", 'F'}, + {"0SOSBE", 'F'}, + {"0SOSBF", 'F'}, + {"0SOSBN", 'F'}, + {"0SOSBS", 'F'}, + {"0SOSBV", 'F'}, + {"0SOSC", 'F'}, + {"0SOSE(", 'F'}, + {"0SOSE1", 'F'}, + {"0SOSEF", 'F'}, + {"0SOSEK", 'F'}, + {"0SOSEN", 'F'}, + {"0SOSEO", 'F'}, + {"0SOSES", 'F'}, + {"0SOSEU", 'F'}, + {"0SOSEV", 'F'}, + {"0SOSF(", 'F'}, + {"0SOSK(", 'F'}, + {"0SOSK)", 'F'}, + {"0SOSK1", 'F'}, + {"0SOSKB", 'F'}, + {"0SOSKF", 'F'}, + {"0SOSKN", 'F'}, + {"0SOSKS", 'F'}, + {"0SOSKU", 'F'}, + {"0SOSKV", 'F'}, + {"0SOSO(", 'F'}, + {"0SOSO1", 'F'}, + {"0SOSOF", 'F'}, + {"0SOSOK", 'F'}, + {"0SOSON", 'F'}, + {"0SOSOS", 'F'}, + {"0SOSOT", 'F'}, + {"0SOSOU", 'F'}, + {"0SOSOV", 'F'}, + {"0SOSU", 'F'}, + {"0SOSU(", 'F'}, + {"0SOSU1", 'F'}, + {"0SOSU;", 'F'}, + {"0SOSUC", 'F'}, + {"0SOSUE", 'F'}, + {"0SOSUF", 'F'}, + {"0SOSUK", 'F'}, + {"0SOSUN", 'F'}, + {"0SOSUO", 'F'}, + {"0SOSUS", 'F'}, + {"0SOSUT", 'F'}, + {"0SOSUV", 'F'}, + {"0SOSV(", 'F'}, + {"0SOSVF", 'F'}, + {"0SOSVO", 'F'}, + {"0SOSVS", 'F'}, + {"0SOSVU", 'F'}, + {"0SOT((", 'F'}, + {"0SOT(1", 'F'}, + {"0SOT(F", 'F'}, + {"0SOT(N", 'F'}, + {"0SOT(S", 'F'}, + {"0SOT(V", 'F'}, + {"0SOU((", 'F'}, + {"0SOU(E", 'F'}, + {"0SOUEK", 'F'}, + {"0SOUEN", 'F'}, + {"0SOV", 'F'}, + {"0SOV&(", 'F'}, + {"0SOV&1", 'F'}, + {"0SOV&E", 'F'}, + {"0SOV&F", 'F'}, + {"0SOV&K", 'F'}, + {"0SOV&N", 'F'}, + {"0SOV&S", 'F'}, + {"0SOV&U", 'F'}, + {"0SOV&V", 'F'}, + {"0SOV((", 'F'}, + {"0SOV(E", 'F'}, + {"0SOV(U", 'F'}, + {"0SOV)&", 'F'}, + {"0SOV))", 'F'}, + {"0SOV),", 'F'}, + {"0SOV);", 'F'}, + {"0SOV)B", 'F'}, + {"0SOV)E", 'F'}, + {"0SOV)K", 'F'}, + {"0SOV)O", 'F'}, + {"0SOV)U", 'F'}, + {"0SOV,(", 'F'}, + {"0SOV,1", 'F'}, + {"0SOV,F", 'F'}, + {"0SOV,N", 'F'}, + {"0SOV,S", 'F'}, + {"0SOV,V", 'F'}, + {"0SOV;", 'F'}, + {"0SOV;C", 'F'}, + {"0SOV;E", 'F'}, + {"0SOV;N", 'F'}, + {"0SOV;T", 'F'}, + {"0SOVA(", 'F'}, + {"0SOVAF", 'F'}, + {"0SOVAS", 'F'}, + {"0SOVAT", 'F'}, + {"0SOVAV", 'F'}, + {"0SOVB(", 'F'}, + {"0SOVB1", 'F'}, + {"0SOVBE", 'F'}, + {"0SOVBF", 'F'}, + {"0SOVBN", 'F'}, + {"0SOVBS", 'F'}, + {"0SOVBV", 'F'}, + {"0SOVC", 'F'}, + {"0SOVE(", 'F'}, + {"0SOVE1", 'F'}, + {"0SOVEF", 'F'}, + {"0SOVEK", 'F'}, + {"0SOVEN", 'F'}, + {"0SOVEO", 'F'}, + {"0SOVES", 'F'}, + {"0SOVEU", 'F'}, + {"0SOVEV", 'F'}, + {"0SOVF(", 'F'}, + {"0SOVK(", 'F'}, + {"0SOVK)", 'F'}, + {"0SOVK1", 'F'}, + {"0SOVKB", 'F'}, + {"0SOVKF", 'F'}, + {"0SOVKN", 'F'}, + {"0SOVKS", 'F'}, + {"0SOVKU", 'F'}, + {"0SOVKV", 'F'}, + {"0SOVO(", 'F'}, + {"0SOVOF", 'F'}, + {"0SOVOK", 'F'}, + {"0SOVOS", 'F'}, + {"0SOVOT", 'F'}, + {"0SOVOU", 'F'}, + {"0SOVS(", 'F'}, + {"0SOVS1", 'F'}, + {"0SOVSF", 'F'}, + {"0SOVSO", 'F'}, + {"0SOVSU", 'F'}, + {"0SOVSV", 'F'}, + {"0SOVU", 'F'}, + {"0SOVU(", 'F'}, + {"0SOVU1", 'F'}, + {"0SOVU;", 'F'}, + {"0SOVUC", 'F'}, + {"0SOVUE", 'F'}, + {"0SOVUF", 'F'}, + {"0SOVUK", 'F'}, + {"0SOVUN", 'F'}, + {"0SOVUO", 'F'}, + {"0SOVUS", 'F'}, + {"0SOVUT", 'F'}, + {"0SOVUV", 'F'}, + {"0SU(((", 'F'}, + {"0SU((1", 'F'}, + {"0SU((E", 'F'}, + {"0SU((F", 'F'}, + {"0SU((N", 'F'}, + {"0SU((S", 'F'}, + {"0SU((V", 'F'}, + {"0SU(1)", 'F'}, + {"0SU(1O", 'F'}, + {"0SU(E(", 'F'}, + {"0SU(E1", 'F'}, + {"0SU(EF", 'F'}, + {"0SU(EK", 'F'}, + {"0SU(EN", 'F'}, + {"0SU(ES", 'F'}, + {"0SU(EV", 'F'}, + {"0SU(F(", 'F'}, + {"0SU(N)", 'F'}, + {"0SU(NO", 'F'}, + {"0SU(S)", 'F'}, + {"0SU(SO", 'F'}, + {"0SU(V)", 'F'}, + {"0SU(VO", 'F'}, + {"0SU1,(", 'F'}, + {"0SU1,F", 'F'}, + {"0SU1,V", 'F'}, + {"0SU1C", 'F'}, + {"0SU1O(", 'F'}, + {"0SU1OF", 'F'}, + {"0SU1OS", 'F'}, + {"0SU1OV", 'F'}, + {"0SU;", 'F'}, + {"0SU;C", 'F'}, + {"0SUC", 'F'}, + {"0SUE", 'F'}, + {"0SUE((", 'F'}, + {"0SUE(1", 'F'}, + {"0SUE(E", 'F'}, + {"0SUE(F", 'F'}, + {"0SUE(N", 'F'}, + {"0SUE(O", 'F'}, + {"0SUE(S", 'F'}, + {"0SUE(V", 'F'}, + {"0SUE1", 'F'}, + {"0SUE1&", 'F'}, + {"0SUE1(", 'F'}, + {"0SUE1)", 'F'}, + {"0SUE1,", 'F'}, + {"0SUE1;", 'F'}, + {"0SUE1B", 'F'}, + {"0SUE1C", 'F'}, + {"0SUE1F", 'F'}, + {"0SUE1K", 'F'}, + {"0SUE1N", 'F'}, + {"0SUE1O", 'F'}, + {"0SUE1S", 'F'}, + {"0SUE1U", 'F'}, + {"0SUE1V", 'F'}, + {"0SUE;", 'F'}, + {"0SUE;C", 'F'}, + {"0SUEC", 'F'}, + {"0SUEF", 'F'}, + {"0SUEF(", 'F'}, + {"0SUEF,", 'F'}, + {"0SUEF;", 'F'}, + {"0SUEFC", 'F'}, + {"0SUEK", 'F'}, + {"0SUEK(", 'F'}, + {"0SUEK1", 'F'}, + {"0SUEK;", 'F'}, + {"0SUEKC", 'F'}, + {"0SUEKF", 'F'}, + {"0SUEKN", 'F'}, + {"0SUEKO", 'F'}, + {"0SUEKS", 'F'}, + {"0SUEKV", 'F'}, + {"0SUEN", 'F'}, + {"0SUEN&", 'F'}, + {"0SUEN(", 'F'}, + {"0SUEN)", 'F'}, + {"0SUEN,", 'F'}, + {"0SUEN1", 'F'}, + {"0SUEN;", 'F'}, + {"0SUENB", 'F'}, + {"0SUENC", 'F'}, + {"0SUENF", 'F'}, + {"0SUENK", 'F'}, + {"0SUENO", 'F'}, + {"0SUENS", 'F'}, + {"0SUENU", 'F'}, + {"0SUEOK", 'F'}, + {"0SUEON", 'F'}, + {"0SUEOO", 'F'}, + {"0SUES", 'F'}, + {"0SUES&", 'F'}, + {"0SUES(", 'F'}, + {"0SUES)", 'F'}, + {"0SUES,", 'F'}, + {"0SUES1", 'F'}, + {"0SUES;", 'F'}, + {"0SUESB", 'F'}, + {"0SUESC", 'F'}, + {"0SUESF", 'F'}, + {"0SUESK", 'F'}, + {"0SUESO", 'F'}, + {"0SUESU", 'F'}, + {"0SUESV", 'F'}, + {"0SUEV", 'F'}, + {"0SUEV&", 'F'}, + {"0SUEV(", 'F'}, + {"0SUEV)", 'F'}, + {"0SUEV,", 'F'}, + {"0SUEV;", 'F'}, + {"0SUEVB", 'F'}, + {"0SUEVC", 'F'}, + {"0SUEVF", 'F'}, + {"0SUEVK", 'F'}, + {"0SUEVN", 'F'}, + {"0SUEVO", 'F'}, + {"0SUEVS", 'F'}, + {"0SUEVU", 'F'}, + {"0SUF((", 'F'}, + {"0SUF()", 'F'}, + {"0SUF(1", 'F'}, + {"0SUF(F", 'F'}, + {"0SUF(N", 'F'}, + {"0SUF(S", 'F'}, + {"0SUF(V", 'F'}, + {"0SUK((", 'F'}, + {"0SUK(E", 'F'}, + {"0SUN((", 'F'}, + {"0SUN(1", 'F'}, + {"0SUN(F", 'F'}, + {"0SUN(S", 'F'}, + {"0SUN(V", 'F'}, + {"0SUN,(", 'F'}, + {"0SUN,F", 'F'}, + {"0SUN,V", 'F'}, + {"0SUN1(", 'F'}, + {"0SUN1,", 'F'}, + {"0SUN1O", 'F'}, + {"0SUNC", 'F'}, + {"0SUNE(", 'F'}, + {"0SUNE1", 'F'}, + {"0SUNEF", 'F'}, + {"0SUNEN", 'F'}, + {"0SUNES", 'F'}, + {"0SUNEV", 'F'}, + {"0SUNF(", 'F'}, + {"0SUNO(", 'F'}, + {"0SUNOF", 'F'}, + {"0SUNOS", 'F'}, + {"0SUNOV", 'F'}, + {"0SUNS(", 'F'}, + {"0SUNS,", 'F'}, + {"0SUNSO", 'F'}, + {"0SUO((", 'F'}, + {"0SUO(E", 'F'}, + {"0SUON(", 'F'}, + {"0SUON1", 'F'}, + {"0SUONF", 'F'}, + {"0SUONS", 'F'}, + {"0SUS,(", 'F'}, + {"0SUS,F", 'F'}, + {"0SUS,V", 'F'}, + {"0SUSC", 'F'}, + {"0SUSO(", 'F'}, + {"0SUSO1", 'F'}, + {"0SUSOF", 'F'}, + {"0SUSON", 'F'}, + {"0SUSOS", 'F'}, + {"0SUSOV", 'F'}, + {"0SUTN(", 'F'}, + {"0SUTN1", 'F'}, + {"0SUTNF", 'F'}, + {"0SUTNS", 'F'}, + {"0SUV,(", 'F'}, + {"0SUV,1", 'F'}, + {"0SUV,F", 'F'}, + {"0SUV,N", 'F'}, + {"0SUV,S", 'F'}, + {"0SUV,V", 'F'}, + {"0SUVC", 'F'}, + {"0SUVO(", 'F'}, + {"0SUVOF", 'F'}, + {"0SUVOS", 'F'}, + {"0SVF((", 'F'}, + {"0SVF()", 'F'}, + {"0SVF(1", 'F'}, + {"0SVF(F", 'F'}, + {"0SVF(N", 'F'}, + {"0SVF(S", 'F'}, + {"0SVF(V", 'F'}, + {"0SVO((", 'F'}, + {"0SVO(1", 'F'}, + {"0SVO(F", 'F'}, + {"0SVO(N", 'F'}, + {"0SVO(S", 'F'}, + {"0SVO(V", 'F'}, + {"0SVOF(", 'F'}, + {"0SVOS(", 'F'}, + {"0SVOS1", 'F'}, + {"0SVOSF", 'F'}, + {"0SVOSO", 'F'}, + {"0SVOSU", 'F'}, + {"0SVOSV", 'F'}, + {"0SVS", 'F'}, + {"0SVS;", 'F'}, + {"0SVS;C", 'F'}, + {"0SVSC", 'F'}, + {"0SVSO(", 'F'}, + {"0SVSO1", 'F'}, + {"0SVSOF", 'F'}, + {"0SVSON", 'F'}, + {"0SVSOS", 'F'}, + {"0SVSOV", 'F'}, + {"0SVUE", 'F'}, + {"0SVUE;", 'F'}, + {"0SVUEC", 'F'}, + {"0SVUEK", 'F'}, + {"0T((((", 'F'}, + {"0T(((1", 'F'}, + {"0T(((F", 'F'}, + {"0T(((N", 'F'}, + {"0T(((S", 'F'}, + {"0T(((V", 'F'}, + {"0T((1(", 'F'}, + {"0T((1)", 'F'}, + {"0T((1F", 'F'}, + {"0T((1N", 'F'}, + {"0T((1O", 'F'}, + {"0T((1S", 'F'}, + {"0T((1V", 'F'}, + {"0T((F(", 'F'}, + {"0T((N(", 'F'}, + {"0T((N)", 'F'}, + {"0T((N1", 'F'}, + {"0T((NF", 'F'}, + {"0T((NO", 'F'}, + {"0T((NS", 'F'}, + {"0T((S(", 'F'}, + {"0T((S)", 'F'}, + {"0T((S1", 'F'}, + {"0T((SF", 'F'}, + {"0T((SN", 'F'}, + {"0T((SO", 'F'}, + {"0T((SV", 'F'}, + {"0T((V(", 'F'}, + {"0T((V)", 'F'}, + {"0T((VF", 'F'}, + {"0T((VO", 'F'}, + {"0T((VS", 'F'}, + {"0T(1))", 'F'}, + {"0T(1)F", 'F'}, + {"0T(1)O", 'F'}, + {"0T(1)U", 'F'}, + {"0T(1F(", 'F'}, + {"0T(1N)", 'F'}, + {"0T(1NO", 'F'}, + {"0T(1O(", 'F'}, + {"0T(1OF", 'F'}, + {"0T(1OS", 'F'}, + {"0T(1OV", 'F'}, + {"0T(1S)", 'F'}, + {"0T(1V)", 'F'}, + {"0T(1VO", 'F'}, + {"0T(F((", 'F'}, + {"0T(F()", 'F'}, + {"0T(F(1", 'F'}, + {"0T(F(F", 'F'}, + {"0T(F(N", 'F'}, + {"0T(F(S", 'F'}, + {"0T(F(V", 'F'}, + {"0T(N((", 'F'}, + {"0T(N(1", 'F'}, + {"0T(N(F", 'F'}, + {"0T(N(S", 'F'}, + {"0T(N(V", 'F'}, + {"0T(N))", 'F'}, + {"0T(N)F", 'F'}, + {"0T(N)O", 'F'}, + {"0T(N)U", 'F'}, + {"0T(N1)", 'F'}, + {"0T(N1O", 'F'}, + {"0T(NF(", 'F'}, + {"0T(NO(", 'F'}, + {"0T(NOF", 'F'}, + {"0T(NOS", 'F'}, + {"0T(NOV", 'F'}, + {"0T(NS)", 'F'}, + {"0T(NSO", 'F'}, + {"0T(S))", 'F'}, + {"0T(S)F", 'F'}, + {"0T(S)O", 'F'}, + {"0T(S)U", 'F'}, + {"0T(S1)", 'F'}, + {"0T(S1O", 'F'}, + {"0T(SF(", 'F'}, + {"0T(SN)", 'F'}, + {"0T(SNO", 'F'}, + {"0T(SO(", 'F'}, + {"0T(SO1", 'F'}, + {"0T(SOF", 'F'}, + {"0T(SON", 'F'}, + {"0T(SOS", 'F'}, + {"0T(SOV", 'F'}, + {"0T(SV)", 'F'}, + {"0T(SVO", 'F'}, + {"0T(V))", 'F'}, + {"0T(V)F", 'F'}, + {"0T(V)O", 'F'}, + {"0T(V)U", 'F'}, + {"0T(VF(", 'F'}, + {"0T(VO(", 'F'}, + {"0T(VOF", 'F'}, + {"0T(VOS", 'F'}, + {"0T(VS)", 'F'}, + {"0T(VSO", 'F'}, + {"0T(VV)", 'F'}, + {"0T1F((", 'F'}, + {"0T1F(1", 'F'}, + {"0T1F(F", 'F'}, + {"0T1F(N", 'F'}, + {"0T1F(S", 'F'}, + {"0T1F(V", 'F'}, + {"0T1O((", 'F'}, + {"0T1O(1", 'F'}, + {"0T1O(F", 'F'}, + {"0T1O(N", 'F'}, + {"0T1O(S", 'F'}, + {"0T1O(V", 'F'}, + {"0T1OF(", 'F'}, + {"0T1OSF", 'F'}, + {"0T1OSO", 'F'}, + {"0T1OVF", 'F'}, + {"0T1OVO", 'F'}, + {"0TF(((", 'F'}, + {"0TF(()", 'F'}, + {"0TF((1", 'F'}, + {"0TF((F", 'F'}, + {"0TF((N", 'F'}, + {"0TF((S", 'F'}, + {"0TF((V", 'F'}, + {"0TF())", 'F'}, + {"0TF()F", 'F'}, + {"0TF()O", 'F'}, + {"0TF(1)", 'F'}, + {"0TF(1O", 'F'}, + {"0TF(F(", 'F'}, + {"0TF(N)", 'F'}, + {"0TF(NO", 'F'}, + {"0TF(S)", 'F'}, + {"0TF(SO", 'F'}, + {"0TF(V)", 'F'}, + {"0TF(VO", 'F'}, + {"0TN(((", 'F'}, + {"0TN((1", 'F'}, + {"0TN((F", 'F'}, + {"0TN((N", 'F'}, + {"0TN((S", 'F'}, + {"0TN((V", 'F'}, + {"0TN(1)", 'F'}, + {"0TN(1O", 'F'}, + {"0TN(F(", 'F'}, + {"0TN(S)", 'F'}, + {"0TN(SO", 'F'}, + {"0TN(V)", 'F'}, + {"0TN(VO", 'F'}, + {"0TN1;", 'F'}, + {"0TN1;C", 'F'}, + {"0TN1O(", 'F'}, + {"0TN1OF", 'F'}, + {"0TN1OS", 'F'}, + {"0TN1OV", 'F'}, + {"0TNF((", 'F'}, + {"0TNF()", 'F'}, + {"0TNF(1", 'F'}, + {"0TNF(F", 'F'}, + {"0TNF(N", 'F'}, + {"0TNF(S", 'F'}, + {"0TNF(V", 'F'}, + {"0TNO((", 'F'}, + {"0TNO(1", 'F'}, + {"0TNO(F", 'F'}, + {"0TNO(N", 'F'}, + {"0TNO(S", 'F'}, + {"0TNO(V", 'F'}, + {"0TNOF(", 'F'}, + {"0TNOSF", 'F'}, + {"0TNOSO", 'F'}, + {"0TNOVF", 'F'}, + {"0TNOVO", 'F'}, + {"0TNS;", 'F'}, + {"0TNS;C", 'F'}, + {"0TNSO(", 'F'}, + {"0TNSO1", 'F'}, + {"0TNSOF", 'F'}, + {"0TNSON", 'F'}, + {"0TNSOS", 'F'}, + {"0TNSOV", 'F'}, + {"0TNV;", 'F'}, + {"0TNVOS", 'F'}, + {"0TO(((", 'F'}, + {"0TO((1", 'F'}, + {"0TO((F", 'F'}, + {"0TO((N", 'F'}, + {"0TO((S", 'F'}, + {"0TO((V", 'F'}, + {"0TO(1)", 'F'}, + {"0TO(1O", 'F'}, + {"0TO(F(", 'F'}, + {"0TO(N)", 'F'}, + {"0TO(NO", 'F'}, + {"0TO(S)", 'F'}, + {"0TO(SO", 'F'}, + {"0TO(V)", 'F'}, + {"0TO(VO", 'F'}, + {"0TO1O(", 'F'}, + {"0TO1OF", 'F'}, + {"0TO1OS", 'F'}, + {"0TO1OV", 'F'}, + {"0TO1UE", 'F'}, + {"0TOF((", 'F'}, + {"0TOF()", 'F'}, + {"0TOF(1", 'F'}, + {"0TOF(F", 'F'}, + {"0TOF(N", 'F'}, + {"0TOF(S", 'F'}, + {"0TOF(V", 'F'}, + {"0TONO(", 'F'}, + {"0TONOF", 'F'}, + {"0TONOS", 'F'}, + {"0TONOV", 'F'}, + {"0TONUE", 'F'}, + {"0TOSO(", 'F'}, + {"0TOSO1", 'F'}, + {"0TOSOF", 'F'}, + {"0TOSON", 'F'}, + {"0TOSOS", 'F'}, + {"0TOSOV", 'F'}, + {"0TOSUE", 'F'}, + {"0TOVO(", 'F'}, + {"0TOVOF", 'F'}, + {"0TOVOS", 'F'}, + {"0TOVUE", 'F'}, + {"0TSF((", 'F'}, + {"0TSF(1", 'F'}, + {"0TSF(F", 'F'}, + {"0TSF(N", 'F'}, + {"0TSF(S", 'F'}, + {"0TSF(V", 'F'}, + {"0TSO((", 'F'}, + {"0TSO(1", 'F'}, + {"0TSO(F", 'F'}, + {"0TSO(N", 'F'}, + {"0TSO(S", 'F'}, + {"0TSO(V", 'F'}, + {"0TSO1F", 'F'}, + {"0TSO1O", 'F'}, + {"0TSOF(", 'F'}, + {"0TSONF", 'F'}, + {"0TSONO", 'F'}, + {"0TSOSF", 'F'}, + {"0TSOSO", 'F'}, + {"0TSOVF", 'F'}, + {"0TSOVO", 'F'}, + {"0TVF((", 'F'}, + {"0TVF(1", 'F'}, + {"0TVF(F", 'F'}, + {"0TVF(N", 'F'}, + {"0TVF(S", 'F'}, + {"0TVF(V", 'F'}, + {"0TVO((", 'F'}, + {"0TVO(1", 'F'}, + {"0TVO(F", 'F'}, + {"0TVO(N", 'F'}, + {"0TVO(S", 'F'}, + {"0TVO(V", 'F'}, + {"0TVOF(", 'F'}, + {"0TVOSF", 'F'}, + {"0TVOSO", 'F'}, + {"0U((((", 'F'}, + {"0U(((E", 'F'}, + {"0U((E(", 'F'}, + {"0U((E1", 'F'}, + {"0U((EF", 'F'}, + {"0U((EK", 'F'}, + {"0U((EN", 'F'}, + {"0U((EO", 'F'}, + {"0U((ES", 'F'}, + {"0U((EV", 'F'}, + {"0U(E((", 'F'}, + {"0U(E(1", 'F'}, + {"0U(E(F", 'F'}, + {"0U(E(K", 'F'}, + {"0U(E(N", 'F'}, + {"0U(E(S", 'F'}, + {"0U(E(V", 'F'}, + {"0U(E1)", 'F'}, + {"0U(E1O", 'F'}, + {"0U(EF(", 'F'}, + {"0U(EK(", 'F'}, + {"0U(EK1", 'F'}, + {"0U(EKF", 'F'}, + {"0U(EKN", 'F'}, + {"0U(EKO", 'F'}, + {"0U(EKS", 'F'}, + {"0U(EKV", 'F'}, + {"0U(EN)", 'F'}, + {"0U(ENK", 'F'}, + {"0U(ENO", 'F'}, + {"0U(EOK", 'F'}, + {"0U(ES)", 'F'}, + {"0U(ESO", 'F'}, + {"0U(EV)", 'F'}, + {"0U(EVO", 'F'}, + {"0UE(((", 'F'}, + {"0UE((1", 'F'}, + {"0UE((F", 'F'}, + {"0UE((N", 'F'}, + {"0UE((S", 'F'}, + {"0UE((V", 'F'}, + {"0UE(1)", 'F'}, + {"0UE(1,", 'F'}, + {"0UE(1O", 'F'}, + {"0UE(F(", 'F'}, + {"0UE(N)", 'F'}, + {"0UE(N,", 'F'}, + {"0UE(NO", 'F'}, + {"0UE(S)", 'F'}, + {"0UE(S,", 'F'}, + {"0UE(SO", 'F'}, + {"0UE(V)", 'F'}, + {"0UE(V,", 'F'}, + {"0UE(VO", 'F'}, + {"0UE1", 'F'}, + {"0UE1,(", 'F'}, + {"0UE1,F", 'F'}, + {"0UE1,V", 'F'}, + {"0UE1;", 'F'}, + {"0UE1;C", 'F'}, + {"0UE1C", 'F'}, + {"0UE1K(", 'F'}, + {"0UE1K1", 'F'}, + {"0UE1KF", 'F'}, + {"0UE1KN", 'F'}, + {"0UE1KS", 'F'}, + {"0UE1KV", 'F'}, + {"0UE1O(", 'F'}, + {"0UE1OF", 'F'}, + {"0UE1OS", 'F'}, + {"0UE1OV", 'F'}, + {"0UEF((", 'F'}, + {"0UEF()", 'F'}, + {"0UEF(1", 'F'}, + {"0UEF(F", 'F'}, + {"0UEF(N", 'F'}, + {"0UEF(S", 'F'}, + {"0UEF(V", 'F'}, + {"0UEK((", 'F'}, + {"0UEK(1", 'F'}, + {"0UEK(F", 'F'}, + {"0UEK(N", 'F'}, + {"0UEK(S", 'F'}, + {"0UEK(V", 'F'}, + {"0UEK1", 'F'}, + {"0UEK1,", 'F'}, + {"0UEK1;", 'F'}, + {"0UEK1C", 'F'}, + {"0UEK1K", 'F'}, + {"0UEK1O", 'F'}, + {"0UEKF(", 'F'}, + {"0UEKN", 'F'}, + {"0UEKN(", 'F'}, + {"0UEKN,", 'F'}, + {"0UEKN;", 'F'}, + {"0UEKNC", 'F'}, + {"0UEKNK", 'F'}, + {"0UEKS", 'F'}, + {"0UEKS,", 'F'}, + {"0UEKS;", 'F'}, + {"0UEKSC", 'F'}, + {"0UEKSK", 'F'}, + {"0UEKSO", 'F'}, + {"0UEKV", 'F'}, + {"0UEKV,", 'F'}, + {"0UEKV;", 'F'}, + {"0UEKVC", 'F'}, + {"0UEKVK", 'F'}, + {"0UEKVO", 'F'}, + {"0UEN", 'F'}, + {"0UEN((", 'F'}, + {"0UEN()", 'F'}, + {"0UEN,(", 'F'}, + {"0UEN,F", 'F'}, + {"0UEN,V", 'F'}, + {"0UEN;", 'F'}, + {"0UEN;C", 'F'}, + {"0UENC", 'F'}, + {"0UENK(", 'F'}, + {"0UENK1", 'F'}, + {"0UENKF", 'F'}, + {"0UENKN", 'F'}, + {"0UENKS", 'F'}, + {"0UENKV", 'F'}, + {"0UENO(", 'F'}, + {"0UENOF", 'F'}, + {"0UENOS", 'F'}, + {"0UENOV", 'F'}, + {"0UES", 'F'}, + {"0UES,(", 'F'}, + {"0UES,F", 'F'}, + {"0UES,V", 'F'}, + {"0UES;", 'F'}, + {"0UES;C", 'F'}, + {"0UESC", 'F'}, + {"0UESK(", 'F'}, + {"0UESK1", 'F'}, + {"0UESKF", 'F'}, + {"0UESKN", 'F'}, + {"0UESKS", 'F'}, + {"0UESKV", 'F'}, + {"0UESO(", 'F'}, + {"0UESO1", 'F'}, + {"0UESOF", 'F'}, + {"0UESON", 'F'}, + {"0UESOS", 'F'}, + {"0UESOV", 'F'}, + {"0UEV", 'F'}, + {"0UEV,(", 'F'}, + {"0UEV,1", 'F'}, + {"0UEV,F", 'F'}, + {"0UEV,N", 'F'}, + {"0UEV,S", 'F'}, + {"0UEV,V", 'F'}, + {"0UEV;", 'F'}, + {"0UEV;C", 'F'}, + {"0UEVC", 'F'}, + {"0UEVK(", 'F'}, + {"0UEVK1", 'F'}, + {"0UEVKF", 'F'}, + {"0UEVKN", 'F'}, + {"0UEVKS", 'F'}, + {"0UEVKV", 'F'}, + {"0UEVO(", 'F'}, + {"0UEVOF", 'F'}, + {"0UEVOS", 'F'}, + {"0UF(((", 'F'}, + {"0UF((1", 'F'}, + {"0UF((F", 'F'}, + {"0UF((N", 'F'}, + {"0UF((S", 'F'}, + {"0UF((V", 'F'}, + {"0UF(1O", 'F'}, + {"0UF(F(", 'F'}, + {"0UF(NO", 'F'}, + {"0UF(SO", 'F'}, + {"0UF(VO", 'F'}, + {"0V&(((", 'F'}, + {"0V&((1", 'F'}, + {"0V&((E", 'F'}, + {"0V&((F", 'F'}, + {"0V&((N", 'F'}, + {"0V&((S", 'F'}, + {"0V&((V", 'F'}, + {"0V&(1&", 'F'}, + {"0V&(1)", 'F'}, + {"0V&(1,", 'F'}, + {"0V&(1O", 'F'}, + {"0V&(E(", 'F'}, + {"0V&(E1", 'F'}, + {"0V&(EF", 'F'}, + {"0V&(EK", 'F'}, + {"0V&(EN", 'F'}, + {"0V&(EO", 'F'}, + {"0V&(ES", 'F'}, + {"0V&(EV", 'F'}, + {"0V&(F(", 'F'}, + {"0V&(N&", 'F'}, + {"0V&(N)", 'F'}, + {"0V&(N,", 'F'}, + {"0V&(NO", 'F'}, + {"0V&(S&", 'F'}, + {"0V&(S)", 'F'}, + {"0V&(S,", 'F'}, + {"0V&(SO", 'F'}, + {"0V&(V&", 'F'}, + {"0V&(V)", 'F'}, + {"0V&(V,", 'F'}, + {"0V&(VO", 'F'}, + {"0V&1", 'F'}, + {"0V&1&(", 'F'}, + {"0V&1&1", 'F'}, + {"0V&1&F", 'F'}, + {"0V&1&N", 'F'}, + {"0V&1&S", 'F'}, + {"0V&1&V", 'F'}, + {"0V&1)&", 'F'}, + {"0V&1))", 'F'}, + {"0V&1)U", 'F'}, + {"0V&1;", 'F'}, + {"0V&1;C", 'F'}, + {"0V&1;E", 'F'}, + {"0V&1;T", 'F'}, + {"0V&1B(", 'F'}, + {"0V&1B1", 'F'}, + {"0V&1BF", 'F'}, + {"0V&1BN", 'F'}, + {"0V&1BS", 'F'}, + {"0V&1BV", 'F'}, + {"0V&1C", 'F'}, + {"0V&1EK", 'F'}, + {"0V&1EN", 'F'}, + {"0V&1F(", 'F'}, + {"0V&1K(", 'F'}, + {"0V&1K1", 'F'}, + {"0V&1KF", 'F'}, + {"0V&1KN", 'F'}, + {"0V&1KS", 'F'}, + {"0V&1KV", 'F'}, + {"0V&1O(", 'F'}, + {"0V&1OF", 'F'}, + {"0V&1OO", 'F'}, + {"0V&1OS", 'F'}, + {"0V&1OV", 'F'}, + {"0V&1TN", 'F'}, + {"0V&1U", 'F'}, + {"0V&1U(", 'F'}, + {"0V&1U;", 'F'}, + {"0V&1UC", 'F'}, + {"0V&1UE", 'F'}, + {"0V&E((", 'F'}, + {"0V&E(1", 'F'}, + {"0V&E(F", 'F'}, + {"0V&E(N", 'F'}, + {"0V&E(O", 'F'}, + {"0V&E(S", 'F'}, + {"0V&E(V", 'F'}, + {"0V&E1", 'F'}, + {"0V&E1;", 'F'}, + {"0V&E1C", 'F'}, + {"0V&E1K", 'F'}, + {"0V&E1O", 'F'}, + {"0V&EF(", 'F'}, + {"0V&EK(", 'F'}, + {"0V&EK1", 'F'}, + {"0V&EKF", 'F'}, + {"0V&EKN", 'F'}, + {"0V&EKS", 'F'}, + {"0V&EKV", 'F'}, + {"0V&EN", 'F'}, + {"0V&EN;", 'F'}, + {"0V&ENC", 'F'}, + {"0V&ENK", 'F'}, + {"0V&ENO", 'F'}, + {"0V&ES", 'F'}, + {"0V&ES;", 'F'}, + {"0V&ESC", 'F'}, + {"0V&ESK", 'F'}, + {"0V&ESO", 'F'}, + {"0V&EV", 'F'}, + {"0V&EV;", 'F'}, + {"0V&EVC", 'F'}, + {"0V&EVK", 'F'}, + {"0V&EVO", 'F'}, + {"0V&F((", 'F'}, + {"0V&F()", 'F'}, + {"0V&F(1", 'F'}, + {"0V&F(F", 'F'}, + {"0V&F(N", 'F'}, + {"0V&F(S", 'F'}, + {"0V&F(V", 'F'}, + {"0V&K&(", 'F'}, + {"0V&K&1", 'F'}, + {"0V&K&F", 'F'}, + {"0V&K&N", 'F'}, + {"0V&K&S", 'F'}, + {"0V&K&V", 'F'}, + {"0V&K((", 'F'}, + {"0V&K(1", 'F'}, + {"0V&K(F", 'F'}, + {"0V&K(N", 'F'}, + {"0V&K(S", 'F'}, + {"0V&K(V", 'F'}, + {"0V&K1O", 'F'}, + {"0V&KF(", 'F'}, + {"0V&KNK", 'F'}, + {"0V&KO(", 'F'}, + {"0V&KO1", 'F'}, + {"0V&KOF", 'F'}, + {"0V&KOK", 'F'}, + {"0V&KON", 'F'}, + {"0V&KOS", 'F'}, + {"0V&KOV", 'F'}, + {"0V&KSO", 'F'}, + {"0V&KVO", 'F'}, + {"0V&N", 'F'}, + {"0V&N&(", 'F'}, + {"0V&N&1", 'F'}, + {"0V&N&F", 'F'}, + {"0V&N&N", 'F'}, + {"0V&N&S", 'F'}, + {"0V&N&V", 'F'}, + {"0V&N)&", 'F'}, + {"0V&N))", 'F'}, + {"0V&N)U", 'F'}, + {"0V&N;", 'F'}, + {"0V&N;C", 'F'}, + {"0V&N;E", 'F'}, + {"0V&N;T", 'F'}, + {"0V&NB(", 'F'}, + {"0V&NB1", 'F'}, + {"0V&NBF", 'F'}, + {"0V&NBN", 'F'}, + {"0V&NBS", 'F'}, + {"0V&NBV", 'F'}, + {"0V&NC", 'F'}, + {"0V&NEN", 'F'}, + {"0V&NF(", 'F'}, + {"0V&NK(", 'F'}, + {"0V&NK1", 'F'}, + {"0V&NKF", 'F'}, + {"0V&NKN", 'F'}, + {"0V&NKS", 'F'}, + {"0V&NKV", 'F'}, + {"0V&NO(", 'F'}, + {"0V&NOF", 'F'}, + {"0V&NOS", 'F'}, + {"0V&NOV", 'F'}, + {"0V&NTN", 'F'}, + {"0V&NU", 'F'}, + {"0V&NU(", 'F'}, + {"0V&NU;", 'F'}, + {"0V&NUC", 'F'}, + {"0V&NUE", 'F'}, + {"0V&S", 'F'}, + {"0V&S&(", 'F'}, + {"0V&S&1", 'F'}, + {"0V&S&F", 'F'}, + {"0V&S&N", 'F'}, + {"0V&S&S", 'F'}, + {"0V&S&V", 'F'}, + {"0V&S)&", 'F'}, + {"0V&S))", 'F'}, + {"0V&S)U", 'F'}, + {"0V&S1", 'F'}, + {"0V&S1;", 'F'}, + {"0V&S1C", 'F'}, + {"0V&S1O", 'F'}, + {"0V&S;", 'F'}, + {"0V&S;C", 'F'}, + {"0V&S;E", 'F'}, + {"0V&S;T", 'F'}, + {"0V&SB(", 'F'}, + {"0V&SB1", 'F'}, + {"0V&SBF", 'F'}, + {"0V&SBN", 'F'}, + {"0V&SBS", 'F'}, + {"0V&SBV", 'F'}, + {"0V&SC", 'F'}, + {"0V&SEK", 'F'}, + {"0V&SEN", 'F'}, + {"0V&SF(", 'F'}, + {"0V&SK(", 'F'}, + {"0V&SK1", 'F'}, + {"0V&SKF", 'F'}, + {"0V&SKN", 'F'}, + {"0V&SKS", 'F'}, + {"0V&SKV", 'F'}, + {"0V&SO(", 'F'}, + {"0V&SO1", 'F'}, + {"0V&SOF", 'F'}, + {"0V&SON", 'F'}, + {"0V&SOO", 'F'}, + {"0V&SOS", 'F'}, + {"0V&SOV", 'F'}, + {"0V&STN", 'F'}, + {"0V&SU", 'F'}, + {"0V&SU(", 'F'}, + {"0V&SU;", 'F'}, + {"0V&SUC", 'F'}, + {"0V&SUE", 'F'}, + {"0V&SV", 'F'}, + {"0V&SV;", 'F'}, + {"0V&SVC", 'F'}, + {"0V&SVO", 'F'}, + {"0V&V", 'F'}, + {"0V&V&(", 'F'}, + {"0V&V&1", 'F'}, + {"0V&V&F", 'F'}, + {"0V&V&N", 'F'}, + {"0V&V&S", 'F'}, + {"0V&V&V", 'F'}, + {"0V&V)&", 'F'}, + {"0V&V))", 'F'}, + {"0V&V)U", 'F'}, + {"0V&V;", 'F'}, + {"0V&V;C", 'F'}, + {"0V&V;E", 'F'}, + {"0V&V;T", 'F'}, + {"0V&VB(", 'F'}, + {"0V&VB1", 'F'}, + {"0V&VBF", 'F'}, + {"0V&VBN", 'F'}, + {"0V&VBS", 'F'}, + {"0V&VBV", 'F'}, + {"0V&VC", 'F'}, + {"0V&VEK", 'F'}, + {"0V&VEN", 'F'}, + {"0V&VF(", 'F'}, + {"0V&VK(", 'F'}, + {"0V&VK1", 'F'}, + {"0V&VKF", 'F'}, + {"0V&VKN", 'F'}, + {"0V&VKS", 'F'}, + {"0V&VKV", 'F'}, + {"0V&VO(", 'F'}, + {"0V&VOF", 'F'}, + {"0V&VOO", 'F'}, + {"0V&VOS", 'F'}, + {"0V&VS", 'F'}, + {"0V&VS;", 'F'}, + {"0V&VSC", 'F'}, + {"0V&VSO", 'F'}, + {"0V&VTN", 'F'}, + {"0V&VU", 'F'}, + {"0V&VU(", 'F'}, + {"0V&VU;", 'F'}, + {"0V&VUC", 'F'}, + {"0V&VUE", 'F'}, + {"0V((((", 'F'}, + {"0V(((E", 'F'}, + {"0V(((U", 'F'}, + {"0V((EK", 'F'}, + {"0V((EN", 'F'}, + {"0V((U(", 'F'}, + {"0V(EKN", 'F'}, + {"0V(ENK", 'F'}, + {"0V(U((", 'F'}, + {"0V(U(E", 'F'}, + {"0V)&((", 'F'}, + {"0V)&(1", 'F'}, + {"0V)&(E", 'F'}, + {"0V)&(F", 'F'}, + {"0V)&(N", 'F'}, + {"0V)&(S", 'F'}, + {"0V)&(V", 'F'}, + {"0V)&1", 'F'}, + {"0V)&1&", 'F'}, + {"0V)&1)", 'F'}, + {"0V)&1;", 'F'}, + {"0V)&1B", 'F'}, + {"0V)&1C", 'F'}, + {"0V)&1F", 'F'}, + {"0V)&1O", 'F'}, + {"0V)&1U", 'F'}, + {"0V)&F(", 'F'}, + {"0V)&N", 'F'}, + {"0V)&N&", 'F'}, + {"0V)&N)", 'F'}, + {"0V)&N;", 'F'}, + {"0V)&NB", 'F'}, + {"0V)&NC", 'F'}, + {"0V)&NF", 'F'}, + {"0V)&NO", 'F'}, + {"0V)&NU", 'F'}, + {"0V)&S", 'F'}, + {"0V)&S&", 'F'}, + {"0V)&S)", 'F'}, + {"0V)&S;", 'F'}, + {"0V)&SB", 'F'}, + {"0V)&SC", 'F'}, + {"0V)&SF", 'F'}, + {"0V)&SO", 'F'}, + {"0V)&SU", 'F'}, + {"0V)&V", 'F'}, + {"0V)&V&", 'F'}, + {"0V)&V)", 'F'}, + {"0V)&V;", 'F'}, + {"0V)&VB", 'F'}, + {"0V)&VC", 'F'}, + {"0V)&VF", 'F'}, + {"0V)&VO", 'F'}, + {"0V)&VU", 'F'}, + {"0V))&(", 'F'}, + {"0V))&1", 'F'}, + {"0V))&F", 'F'}, + {"0V))&N", 'F'}, + {"0V))&S", 'F'}, + {"0V))&V", 'F'}, + {"0V)))&", 'F'}, + {"0V))))", 'F'}, + {"0V))),", 'F'}, + {"0V)));", 'F'}, + {"0V)))B", 'F'}, + {"0V)))E", 'F'}, + {"0V)))K", 'F'}, + {"0V)))O", 'F'}, + {"0V)))U", 'F'}, + {"0V)),(", 'F'}, + {"0V));E", 'F'}, + {"0V));T", 'F'}, + {"0V))B(", 'F'}, + {"0V))B1", 'F'}, + {"0V))BF", 'F'}, + {"0V))BN", 'F'}, + {"0V))BS", 'F'}, + {"0V))BV", 'F'}, + {"0V))E(", 'F'}, + {"0V))E1", 'F'}, + {"0V))EF", 'F'}, + {"0V))EK", 'F'}, + {"0V))EN", 'F'}, + {"0V))ES", 'F'}, + {"0V))EV", 'F'}, + {"0V))K(", 'F'}, + {"0V))K1", 'F'}, + {"0V))KB", 'F'}, + {"0V))KF", 'F'}, + {"0V))KN", 'F'}, + {"0V))KS", 'F'}, + {"0V))KU", 'F'}, + {"0V))KV", 'F'}, + {"0V))O(", 'F'}, + {"0V))O1", 'F'}, + {"0V))OF", 'F'}, + {"0V))ON", 'F'}, + {"0V))OS", 'F'}, + {"0V))OV", 'F'}, + {"0V))U(", 'F'}, + {"0V))UE", 'F'}, + {"0V),((", 'F'}, + {"0V),(1", 'F'}, + {"0V),(F", 'F'}, + {"0V),(N", 'F'}, + {"0V),(S", 'F'}, + {"0V),(V", 'F'}, + {"0V);E(", 'F'}, + {"0V);E1", 'F'}, + {"0V);EF", 'F'}, + {"0V);EK", 'F'}, + {"0V);EN", 'F'}, + {"0V);EO", 'F'}, + {"0V);ES", 'F'}, + {"0V);EV", 'F'}, + {"0V);T(", 'F'}, + {"0V);T1", 'F'}, + {"0V);TF", 'F'}, + {"0V);TK", 'F'}, + {"0V);TN", 'F'}, + {"0V);TO", 'F'}, + {"0V);TS", 'F'}, + {"0V);TV", 'F'}, + {"0V)B((", 'F'}, + {"0V)B(1", 'F'}, + {"0V)B(F", 'F'}, + {"0V)B(N", 'F'}, + {"0V)B(S", 'F'}, + {"0V)B(V", 'F'}, + {"0V)B1", 'F'}, + {"0V)B1&", 'F'}, + {"0V)B1;", 'F'}, + {"0V)B1C", 'F'}, + {"0V)B1K", 'F'}, + {"0V)B1N", 'F'}, + {"0V)B1O", 'F'}, + {"0V)B1U", 'F'}, + {"0V)BF(", 'F'}, + {"0V)BN", 'F'}, + {"0V)BN&", 'F'}, + {"0V)BN;", 'F'}, + {"0V)BNC", 'F'}, + {"0V)BNK", 'F'}, + {"0V)BNO", 'F'}, + {"0V)BNU", 'F'}, + {"0V)BS", 'F'}, + {"0V)BS&", 'F'}, + {"0V)BS;", 'F'}, + {"0V)BSC", 'F'}, + {"0V)BSK", 'F'}, + {"0V)BSO", 'F'}, + {"0V)BSU", 'F'}, + {"0V)BV", 'F'}, + {"0V)BV&", 'F'}, + {"0V)BV;", 'F'}, + {"0V)BVC", 'F'}, + {"0V)BVK", 'F'}, + {"0V)BVO", 'F'}, + {"0V)BVU", 'F'}, + {"0V)E((", 'F'}, + {"0V)E(1", 'F'}, + {"0V)E(F", 'F'}, + {"0V)E(N", 'F'}, + {"0V)E(S", 'F'}, + {"0V)E(V", 'F'}, + {"0V)E1C", 'F'}, + {"0V)E1O", 'F'}, + {"0V)EF(", 'F'}, + {"0V)EK(", 'F'}, + {"0V)EK1", 'F'}, + {"0V)EKF", 'F'}, + {"0V)EKN", 'F'}, + {"0V)EKS", 'F'}, + {"0V)EKV", 'F'}, + {"0V)ENC", 'F'}, + {"0V)ENO", 'F'}, + {"0V)ESC", 'F'}, + {"0V)ESO", 'F'}, + {"0V)EVC", 'F'}, + {"0V)EVO", 'F'}, + {"0V)K((", 'F'}, + {"0V)K(1", 'F'}, + {"0V)K(F", 'F'}, + {"0V)K(N", 'F'}, + {"0V)K(S", 'F'}, + {"0V)K(V", 'F'}, + {"0V)K1&", 'F'}, + {"0V)K1;", 'F'}, + {"0V)K1B", 'F'}, + {"0V)K1E", 'F'}, + {"0V)K1O", 'F'}, + {"0V)K1U", 'F'}, + {"0V)KB(", 'F'}, + {"0V)KB1", 'F'}, + {"0V)KBF", 'F'}, + {"0V)KBN", 'F'}, + {"0V)KBS", 'F'}, + {"0V)KBV", 'F'}, + {"0V)KF(", 'F'}, + {"0V)KN&", 'F'}, + {"0V)KN;", 'F'}, + {"0V)KNB", 'F'}, + {"0V)KNE", 'F'}, + {"0V)KNK", 'F'}, + {"0V)KNU", 'F'}, + {"0V)KS&", 'F'}, + {"0V)KS;", 'F'}, + {"0V)KSB", 'F'}, + {"0V)KSE", 'F'}, + {"0V)KSO", 'F'}, + {"0V)KSU", 'F'}, + {"0V)KUE", 'F'}, + {"0V)KV&", 'F'}, + {"0V)KV;", 'F'}, + {"0V)KVB", 'F'}, + {"0V)KVE", 'F'}, + {"0V)KVO", 'F'}, + {"0V)KVU", 'F'}, + {"0V)O((", 'F'}, + {"0V)O(1", 'F'}, + {"0V)O(E", 'F'}, + {"0V)O(F", 'F'}, + {"0V)O(N", 'F'}, + {"0V)O(S", 'F'}, + {"0V)O(V", 'F'}, + {"0V)O1", 'F'}, + {"0V)O1&", 'F'}, + {"0V)O1)", 'F'}, + {"0V)O1;", 'F'}, + {"0V)O1B", 'F'}, + {"0V)O1C", 'F'}, + {"0V)O1K", 'F'}, + {"0V)O1O", 'F'}, + {"0V)O1U", 'F'}, + {"0V)OF(", 'F'}, + {"0V)ON", 'F'}, + {"0V)ON&", 'F'}, + {"0V)ON)", 'F'}, + {"0V)ON;", 'F'}, + {"0V)ONB", 'F'}, + {"0V)ONC", 'F'}, + {"0V)ONK", 'F'}, + {"0V)ONO", 'F'}, + {"0V)ONU", 'F'}, + {"0V)OS", 'F'}, + {"0V)OS&", 'F'}, + {"0V)OS)", 'F'}, + {"0V)OS;", 'F'}, + {"0V)OSB", 'F'}, + {"0V)OSC", 'F'}, + {"0V)OSK", 'F'}, + {"0V)OSO", 'F'}, + {"0V)OSU", 'F'}, + {"0V)OV", 'F'}, + {"0V)OV&", 'F'}, + {"0V)OV)", 'F'}, + {"0V)OV;", 'F'}, + {"0V)OVB", 'F'}, + {"0V)OVC", 'F'}, + {"0V)OVK", 'F'}, + {"0V)OVO", 'F'}, + {"0V)OVU", 'F'}, + {"0V)U((", 'F'}, + {"0V)U(E", 'F'}, + {"0V)UE(", 'F'}, + {"0V)UE1", 'F'}, + {"0V)UEF", 'F'}, + {"0V)UEK", 'F'}, + {"0V)UEN", 'F'}, + {"0V)UES", 'F'}, + {"0V)UEV", 'F'}, + {"0V,(((", 'F'}, + {"0V,((1", 'F'}, + {"0V,((E", 'F'}, + {"0V,((F", 'F'}, + {"0V,((N", 'F'}, + {"0V,((S", 'F'}, + {"0V,((V", 'F'}, + {"0V,(1)", 'F'}, + {"0V,(1O", 'F'}, + {"0V,(E(", 'F'}, + {"0V,(E1", 'F'}, + {"0V,(EF", 'F'}, + {"0V,(EK", 'F'}, + {"0V,(EN", 'F'}, + {"0V,(ES", 'F'}, + {"0V,(EV", 'F'}, + {"0V,(F(", 'F'}, + {"0V,(N)", 'F'}, + {"0V,(NO", 'F'}, + {"0V,(S)", 'F'}, + {"0V,(SO", 'F'}, + {"0V,(V)", 'F'}, + {"0V,(VO", 'F'}, + {"0V,1))", 'F'}, + {"0V,1),", 'F'}, + {"0V,1)O", 'F'}, + {"0V,1B(", 'F'}, + {"0V,1B1", 'F'}, + {"0V,1BF", 'F'}, + {"0V,1BN", 'F'}, + {"0V,1BS", 'F'}, + {"0V,1BV", 'F'}, + {"0V,1O(", 'F'}, + {"0V,1OF", 'F'}, + {"0V,1OS", 'F'}, + {"0V,1OV", 'F'}, + {"0V,1UE", 'F'}, + {"0V,F((", 'F'}, + {"0V,F()", 'F'}, + {"0V,F(1", 'F'}, + {"0V,F(F", 'F'}, + {"0V,F(N", 'F'}, + {"0V,F(S", 'F'}, + {"0V,F(T", 'F'}, + {"0V,F(V", 'F'}, + {"0V,N))", 'F'}, + {"0V,N),", 'F'}, + {"0V,N)O", 'F'}, + {"0V,NB(", 'F'}, + {"0V,NB1", 'F'}, + {"0V,NBF", 'F'}, + {"0V,NBN", 'F'}, + {"0V,NBS", 'F'}, + {"0V,NBV", 'F'}, + {"0V,NO(", 'F'}, + {"0V,NOF", 'F'}, + {"0V,NOS", 'F'}, + {"0V,NOV", 'F'}, + {"0V,NUE", 'F'}, + {"0V,S))", 'F'}, + {"0V,S),", 'F'}, + {"0V,S)O", 'F'}, + {"0V,SB(", 'F'}, + {"0V,SB1", 'F'}, + {"0V,SBF", 'F'}, + {"0V,SBN", 'F'}, + {"0V,SBS", 'F'}, + {"0V,SBV", 'F'}, + {"0V,SO(", 'F'}, + {"0V,SO1", 'F'}, + {"0V,SOF", 'F'}, + {"0V,SON", 'F'}, + {"0V,SOS", 'F'}, + {"0V,SOV", 'F'}, + {"0V,SUE", 'F'}, + {"0V,V))", 'F'}, + {"0V,V),", 'F'}, + {"0V,V)O", 'F'}, + {"0V,VB(", 'F'}, + {"0V,VB1", 'F'}, + {"0V,VBF", 'F'}, + {"0V,VBN", 'F'}, + {"0V,VBS", 'F'}, + {"0V,VBV", 'F'}, + {"0V,VO(", 'F'}, + {"0V,VOF", 'F'}, + {"0V,VOS", 'F'}, + {"0V,VUE", 'F'}, + {"0V;E((", 'F'}, + {"0V;E(1", 'F'}, + {"0V;E(E", 'F'}, + {"0V;E(F", 'F'}, + {"0V;E(N", 'F'}, + {"0V;E(S", 'F'}, + {"0V;E(V", 'F'}, + {"0V;E1,", 'F'}, + {"0V;E1;", 'F'}, + {"0V;E1C", 'F'}, + {"0V;E1O", 'F'}, + {"0V;E1T", 'F'}, + {"0V;EF(", 'F'}, + {"0V;EK(", 'F'}, + {"0V;EK1", 'F'}, + {"0V;EKF", 'F'}, + {"0V;EKN", 'F'}, + {"0V;EKO", 'F'}, + {"0V;EKS", 'F'}, + {"0V;EKV", 'F'}, + {"0V;EN,", 'F'}, + {"0V;EN;", 'F'}, + {"0V;ENC", 'F'}, + {"0V;ENK", 'F'}, + {"0V;ENO", 'F'}, + {"0V;ENT", 'F'}, + {"0V;EO(", 'F'}, + {"0V;ES,", 'F'}, + {"0V;ES;", 'F'}, + {"0V;ESC", 'F'}, + {"0V;ESO", 'F'}, + {"0V;EST", 'F'}, + {"0V;EV,", 'F'}, + {"0V;EV;", 'F'}, + {"0V;EVC", 'F'}, + {"0V;EVO", 'F'}, + {"0V;EVT", 'F'}, + {"0V;N:T", 'F'}, + {"0V;T((", 'F'}, + {"0V;T(1", 'F'}, + {"0V;T(E", 'F'}, + {"0V;T(F", 'F'}, + {"0V;T(N", 'F'}, + {"0V;T(S", 'F'}, + {"0V;T(V", 'F'}, + {"0V;T1,", 'F'}, + {"0V;T1;", 'F'}, + {"0V;T1C", 'F'}, + {"0V;T1F", 'F'}, + {"0V;T1O", 'F'}, + {"0V;T1T", 'F'}, + {"0V;T;", 'F'}, + {"0V;T;C", 'F'}, + {"0V;TF(", 'F'}, + {"0V;TK(", 'F'}, + {"0V;TK1", 'F'}, + {"0V;TKF", 'F'}, + {"0V;TKK", 'F'}, + {"0V;TKN", 'F'}, + {"0V;TKO", 'F'}, + {"0V;TKS", 'F'}, + {"0V;TKV", 'F'}, + {"0V;TN(", 'F'}, + {"0V;TN,", 'F'}, + {"0V;TN1", 'F'}, + {"0V;TN;", 'F'}, + {"0V;TNC", 'F'}, + {"0V;TNE", 'F'}, + {"0V;TNF", 'F'}, + {"0V;TNK", 'F'}, + {"0V;TNN", 'F'}, + {"0V;TNO", 'F'}, + {"0V;TNS", 'F'}, + {"0V;TNT", 'F'}, + {"0V;TNV", 'F'}, + {"0V;TO(", 'F'}, + {"0V;TS,", 'F'}, + {"0V;TS;", 'F'}, + {"0V;TSC", 'F'}, + {"0V;TSF", 'F'}, + {"0V;TSO", 'F'}, + {"0V;TST", 'F'}, + {"0V;TT(", 'F'}, + {"0V;TT1", 'F'}, + {"0V;TTF", 'F'}, + {"0V;TTN", 'F'}, + {"0V;TTS", 'F'}, + {"0V;TTV", 'F'}, + {"0V;TV,", 'F'}, + {"0V;TV;", 'F'}, + {"0V;TVC", 'F'}, + {"0V;TVF", 'F'}, + {"0V;TVO", 'F'}, + {"0V;TVT", 'F'}, + {"0VA(((", 'F'}, + {"0VA((1", 'F'}, + {"0VA((F", 'F'}, + {"0VA((N", 'F'}, + {"0VA((S", 'F'}, + {"0VA((V", 'F'}, + {"0VA(F(", 'F'}, + {"0VA(N)", 'F'}, + {"0VA(NO", 'F'}, + {"0VA(S)", 'F'}, + {"0VA(SO", 'F'}, + {"0VA(V)", 'F'}, + {"0VA(VO", 'F'}, + {"0VAF((", 'F'}, + {"0VAF()", 'F'}, + {"0VAF(1", 'F'}, + {"0VAF(F", 'F'}, + {"0VAF(N", 'F'}, + {"0VAF(S", 'F'}, + {"0VAF(V", 'F'}, + {"0VASO(", 'F'}, + {"0VASO1", 'F'}, + {"0VASOF", 'F'}, + {"0VASON", 'F'}, + {"0VASOS", 'F'}, + {"0VASOV", 'F'}, + {"0VASUE", 'F'}, + {"0VATO(", 'F'}, + {"0VATO1", 'F'}, + {"0VATOF", 'F'}, + {"0VATON", 'F'}, + {"0VATOS", 'F'}, + {"0VATOV", 'F'}, + {"0VATUE", 'F'}, + {"0VAVO(", 'F'}, + {"0VAVOF", 'F'}, + {"0VAVOS", 'F'}, + {"0VAVUE", 'F'}, + {"0VB(((", 'F'}, + {"0VB((1", 'F'}, + {"0VB((F", 'F'}, + {"0VB((N", 'F'}, + {"0VB((S", 'F'}, + {"0VB((V", 'F'}, + {"0VB(1)", 'F'}, + {"0VB(1O", 'F'}, + {"0VB(F(", 'F'}, + {"0VB(N)", 'F'}, + {"0VB(NO", 'F'}, + {"0VB(S)", 'F'}, + {"0VB(SO", 'F'}, + {"0VB(V)", 'F'}, + {"0VB(VO", 'F'}, + {"0VB1", 'F'}, + {"0VB1&(", 'F'}, + {"0VB1&1", 'F'}, + {"0VB1&F", 'F'}, + {"0VB1&N", 'F'}, + {"0VB1&S", 'F'}, + {"0VB1&V", 'F'}, + {"0VB1,(", 'F'}, + {"0VB1,F", 'F'}, + {"0VB1,V", 'F'}, + {"0VB1;", 'F'}, + {"0VB1;C", 'F'}, + {"0VB1B(", 'F'}, + {"0VB1B1", 'F'}, + {"0VB1BF", 'F'}, + {"0VB1BN", 'F'}, + {"0VB1BS", 'F'}, + {"0VB1BV", 'F'}, + {"0VB1C", 'F'}, + {"0VB1K(", 'F'}, + {"0VB1K1", 'F'}, + {"0VB1KF", 'F'}, + {"0VB1KN", 'F'}, + {"0VB1KS", 'F'}, + {"0VB1KV", 'F'}, + {"0VB1O(", 'F'}, + {"0VB1OF", 'F'}, + {"0VB1OS", 'F'}, + {"0VB1OV", 'F'}, + {"0VB1U(", 'F'}, + {"0VB1UE", 'F'}, + {"0VBE((", 'F'}, + {"0VBE(1", 'F'}, + {"0VBE(F", 'F'}, + {"0VBE(N", 'F'}, + {"0VBE(S", 'F'}, + {"0VBE(V", 'F'}, + {"0VBEK(", 'F'}, + {"0VBF((", 'F'}, + {"0VBF()", 'F'}, + {"0VBF(1", 'F'}, + {"0VBF(F", 'F'}, + {"0VBF(N", 'F'}, + {"0VBF(S", 'F'}, + {"0VBF(V", 'F'}, + {"0VBN", 'F'}, + {"0VBN&(", 'F'}, + {"0VBN&1", 'F'}, + {"0VBN&F", 'F'}, + {"0VBN&N", 'F'}, + {"0VBN&S", 'F'}, + {"0VBN&V", 'F'}, + {"0VBN,(", 'F'}, + {"0VBN,F", 'F'}, + {"0VBN,V", 'F'}, + {"0VBN;", 'F'}, + {"0VBN;C", 'F'}, + {"0VBNB(", 'F'}, + {"0VBNB1", 'F'}, + {"0VBNBF", 'F'}, + {"0VBNBN", 'F'}, + {"0VBNBS", 'F'}, + {"0VBNBV", 'F'}, + {"0VBNC", 'F'}, + {"0VBNK(", 'F'}, + {"0VBNK1", 'F'}, + {"0VBNKF", 'F'}, + {"0VBNKN", 'F'}, + {"0VBNKS", 'F'}, + {"0VBNKV", 'F'}, + {"0VBNO(", 'F'}, + {"0VBNOF", 'F'}, + {"0VBNOS", 'F'}, + {"0VBNOV", 'F'}, + {"0VBNU(", 'F'}, + {"0VBNUE", 'F'}, + {"0VBS", 'F'}, + {"0VBS&(", 'F'}, + {"0VBS&1", 'F'}, + {"0VBS&F", 'F'}, + {"0VBS&N", 'F'}, + {"0VBS&S", 'F'}, + {"0VBS&V", 'F'}, + {"0VBS,(", 'F'}, + {"0VBS,F", 'F'}, + {"0VBS,V", 'F'}, + {"0VBS;", 'F'}, + {"0VBS;C", 'F'}, + {"0VBSB(", 'F'}, + {"0VBSB1", 'F'}, + {"0VBSBF", 'F'}, + {"0VBSBN", 'F'}, + {"0VBSBS", 'F'}, + {"0VBSBV", 'F'}, + {"0VBSC", 'F'}, + {"0VBSK(", 'F'}, + {"0VBSK1", 'F'}, + {"0VBSKF", 'F'}, + {"0VBSKN", 'F'}, + {"0VBSKS", 'F'}, + {"0VBSKV", 'F'}, + {"0VBSO(", 'F'}, + {"0VBSO1", 'F'}, + {"0VBSOF", 'F'}, + {"0VBSON", 'F'}, + {"0VBSOS", 'F'}, + {"0VBSOV", 'F'}, + {"0VBSU(", 'F'}, + {"0VBSUE", 'F'}, + {"0VBV", 'F'}, + {"0VBV&(", 'F'}, + {"0VBV&1", 'F'}, + {"0VBV&F", 'F'}, + {"0VBV&N", 'F'}, + {"0VBV&S", 'F'}, + {"0VBV&V", 'F'}, + {"0VBV,(", 'F'}, + {"0VBV,1", 'F'}, + {"0VBV,F", 'F'}, + {"0VBV,N", 'F'}, + {"0VBV,S", 'F'}, + {"0VBV,V", 'F'}, + {"0VBV;", 'F'}, + {"0VBV;C", 'F'}, + {"0VBVB(", 'F'}, + {"0VBVB1", 'F'}, + {"0VBVBF", 'F'}, + {"0VBVBN", 'F'}, + {"0VBVBS", 'F'}, + {"0VBVBV", 'F'}, + {"0VBVC", 'F'}, + {"0VBVK(", 'F'}, + {"0VBVK1", 'F'}, + {"0VBVKF", 'F'}, + {"0VBVKN", 'F'}, + {"0VBVKS", 'F'}, + {"0VBVKV", 'F'}, + {"0VBVO(", 'F'}, + {"0VBVOF", 'F'}, + {"0VBVOS", 'F'}, + {"0VBVU(", 'F'}, + {"0VBVUE", 'F'}, + {"0VC", 'F'}, + {"0VE(((", 'F'}, + {"0VE((1", 'F'}, + {"0VE((F", 'F'}, + {"0VE((N", 'F'}, + {"0VE((S", 'F'}, + {"0VE((V", 'F'}, + {"0VE(1)", 'F'}, + {"0VE(1O", 'F'}, + {"0VE(F(", 'F'}, + {"0VE(N)", 'F'}, + {"0VE(NO", 'F'}, + {"0VE(S)", 'F'}, + {"0VE(SO", 'F'}, + {"0VE(V)", 'F'}, + {"0VE(VO", 'F'}, + {"0VE1C", 'F'}, + {"0VE1O(", 'F'}, + {"0VE1OF", 'F'}, + {"0VE1OS", 'F'}, + {"0VE1OV", 'F'}, + {"0VE1UE", 'F'}, + {"0VEF((", 'F'}, + {"0VEF()", 'F'}, + {"0VEF(1", 'F'}, + {"0VEF(F", 'F'}, + {"0VEF(N", 'F'}, + {"0VEF(S", 'F'}, + {"0VEF(V", 'F'}, + {"0VEK((", 'F'}, + {"0VEK(1", 'F'}, + {"0VEK(E", 'F'}, + {"0VEK(F", 'F'}, + {"0VEK(N", 'F'}, + {"0VEK(S", 'F'}, + {"0VEK(V", 'F'}, + {"0VEK1C", 'F'}, + {"0VEK1O", 'F'}, + {"0VEK1U", 'F'}, + {"0VEKF(", 'F'}, + {"0VEKNC", 'F'}, + {"0VEKNE", 'F'}, + {"0VEKNU", 'F'}, + {"0VEKOK", 'F'}, + {"0VEKSC", 'F'}, + {"0VEKSO", 'F'}, + {"0VEKSU", 'F'}, + {"0VEKU(", 'F'}, + {"0VEKU1", 'F'}, + {"0VEKUE", 'F'}, + {"0VEKUF", 'F'}, + {"0VEKUN", 'F'}, + {"0VEKUS", 'F'}, + {"0VEKUV", 'F'}, + {"0VEKVC", 'F'}, + {"0VEKVO", 'F'}, + {"0VEKVU", 'F'}, + {"0VENC", 'F'}, + {"0VENEN", 'F'}, + {"0VENO(", 'F'}, + {"0VENOF", 'F'}, + {"0VENOS", 'F'}, + {"0VENOV", 'F'}, + {"0VENUE", 'F'}, + {"0VEOKN", 'F'}, + {"0VESC", 'F'}, + {"0VESO(", 'F'}, + {"0VESO1", 'F'}, + {"0VESOF", 'F'}, + {"0VESON", 'F'}, + {"0VESOS", 'F'}, + {"0VESOV", 'F'}, + {"0VESUE", 'F'}, + {"0VEU((", 'F'}, + {"0VEU(1", 'F'}, + {"0VEU(F", 'F'}, + {"0VEU(N", 'F'}, + {"0VEU(S", 'F'}, + {"0VEU(V", 'F'}, + {"0VEU1,", 'F'}, + {"0VEU1C", 'F'}, + {"0VEU1O", 'F'}, + {"0VEUEF", 'F'}, + {"0VEUEK", 'F'}, + {"0VEUF(", 'F'}, + {"0VEUN,", 'F'}, + {"0VEUNC", 'F'}, + {"0VEUNO", 'F'}, + {"0VEUS,", 'F'}, + {"0VEUSC", 'F'}, + {"0VEUSO", 'F'}, + {"0VEUV,", 'F'}, + {"0VEUVC", 'F'}, + {"0VEUVO", 'F'}, + {"0VEVC", 'F'}, + {"0VEVO(", 'F'}, + {"0VEVOF", 'F'}, + {"0VEVOS", 'F'}, + {"0VEVUE", 'F'}, + {"0VF(((", 'F'}, + {"0VF(()", 'F'}, + {"0VF((1", 'F'}, + {"0VF((F", 'F'}, + {"0VF((N", 'F'}, + {"0VF((S", 'F'}, + {"0VF((V", 'F'}, + {"0VF())", 'F'}, + {"0VF()1", 'F'}, + {"0VF()F", 'F'}, + {"0VF()K", 'F'}, + {"0VF()N", 'F'}, + {"0VF()O", 'F'}, + {"0VF()S", 'F'}, + {"0VF()U", 'F'}, + {"0VF()V", 'F'}, + {"0VF(1)", 'F'}, + {"0VF(1N", 'F'}, + {"0VF(1O", 'F'}, + {"0VF(F(", 'F'}, + {"0VF(N)", 'F'}, + {"0VF(N,", 'F'}, + {"0VF(NO", 'F'}, + {"0VF(S)", 'F'}, + {"0VF(SO", 'F'}, + {"0VF(V)", 'F'}, + {"0VF(VO", 'F'}, + {"0VK(((", 'F'}, + {"0VK((1", 'F'}, + {"0VK((F", 'F'}, + {"0VK((N", 'F'}, + {"0VK((S", 'F'}, + {"0VK((V", 'F'}, + {"0VK(1)", 'F'}, + {"0VK(1O", 'F'}, + {"0VK(F(", 'F'}, + {"0VK(N)", 'F'}, + {"0VK(NO", 'F'}, + {"0VK(S)", 'F'}, + {"0VK(SO", 'F'}, + {"0VK(V)", 'F'}, + {"0VK(VO", 'F'}, + {"0VK)&(", 'F'}, + {"0VK)&1", 'F'}, + {"0VK)&F", 'F'}, + {"0VK)&N", 'F'}, + {"0VK)&S", 'F'}, + {"0VK)&V", 'F'}, + {"0VK))&", 'F'}, + {"0VK)))", 'F'}, + {"0VK));", 'F'}, + {"0VK))B", 'F'}, + {"0VK))E", 'F'}, + {"0VK))K", 'F'}, + {"0VK))O", 'F'}, + {"0VK))U", 'F'}, + {"0VK);E", 'F'}, + {"0VK);T", 'F'}, + {"0VK)B(", 'F'}, + {"0VK)B1", 'F'}, + {"0VK)BF", 'F'}, + {"0VK)BN", 'F'}, + {"0VK)BS", 'F'}, + {"0VK)BV", 'F'}, + {"0VK)E(", 'F'}, + {"0VK)E1", 'F'}, + {"0VK)EF", 'F'}, + {"0VK)EK", 'F'}, + {"0VK)EN", 'F'}, + {"0VK)ES", 'F'}, + {"0VK)EV", 'F'}, + {"0VK)OF", 'F'}, + {"0VK)UE", 'F'}, + {"0VK1", 'F'}, + {"0VK1&(", 'F'}, + {"0VK1&1", 'F'}, + {"0VK1&F", 'F'}, + {"0VK1&N", 'F'}, + {"0VK1&S", 'F'}, + {"0VK1&V", 'F'}, + {"0VK1;", 'F'}, + {"0VK1;C", 'F'}, + {"0VK1;E", 'F'}, + {"0VK1;T", 'F'}, + {"0VK1B(", 'F'}, + {"0VK1B1", 'F'}, + {"0VK1BF", 'F'}, + {"0VK1BN", 'F'}, + {"0VK1BS", 'F'}, + {"0VK1BV", 'F'}, + {"0VK1C", 'F'}, + {"0VK1E(", 'F'}, + {"0VK1E1", 'F'}, + {"0VK1EF", 'F'}, + {"0VK1EK", 'F'}, + {"0VK1EN", 'F'}, + {"0VK1ES", 'F'}, + {"0VK1EV", 'F'}, + {"0VK1O(", 'F'}, + {"0VK1OF", 'F'}, + {"0VK1OS", 'F'}, + {"0VK1OV", 'F'}, + {"0VK1U(", 'F'}, + {"0VK1UE", 'F'}, + {"0VKF((", 'F'}, + {"0VKF()", 'F'}, + {"0VKF(1", 'F'}, + {"0VKF(F", 'F'}, + {"0VKF(N", 'F'}, + {"0VKF(S", 'F'}, + {"0VKF(V", 'F'}, + {"0VKN", 'F'}, + {"0VKN&(", 'F'}, + {"0VKN&1", 'F'}, + {"0VKN&F", 'F'}, + {"0VKN&N", 'F'}, + {"0VKN&S", 'F'}, + {"0VKN&V", 'F'}, + {"0VKN;", 'F'}, + {"0VKN;C", 'F'}, + {"0VKN;E", 'F'}, + {"0VKN;T", 'F'}, + {"0VKNB(", 'F'}, + {"0VKNB1", 'F'}, + {"0VKNBF", 'F'}, + {"0VKNBN", 'F'}, + {"0VKNBS", 'F'}, + {"0VKNBV", 'F'}, + {"0VKNC", 'F'}, + {"0VKNE(", 'F'}, + {"0VKNE1", 'F'}, + {"0VKNEF", 'F'}, + {"0VKNEN", 'F'}, + {"0VKNES", 'F'}, + {"0VKNEV", 'F'}, + {"0VKNU(", 'F'}, + {"0VKNUE", 'F'}, + {"0VKS", 'F'}, + {"0VKS&(", 'F'}, + {"0VKS&1", 'F'}, + {"0VKS&F", 'F'}, + {"0VKS&N", 'F'}, + {"0VKS&S", 'F'}, + {"0VKS&V", 'F'}, + {"0VKS;", 'F'}, + {"0VKS;C", 'F'}, + {"0VKS;E", 'F'}, + {"0VKS;T", 'F'}, + {"0VKSB(", 'F'}, + {"0VKSB1", 'F'}, + {"0VKSBF", 'F'}, + {"0VKSBN", 'F'}, + {"0VKSBS", 'F'}, + {"0VKSBV", 'F'}, + {"0VKSC", 'F'}, + {"0VKSE(", 'F'}, + {"0VKSE1", 'F'}, + {"0VKSEF", 'F'}, + {"0VKSEK", 'F'}, + {"0VKSEN", 'F'}, + {"0VKSES", 'F'}, + {"0VKSEV", 'F'}, + {"0VKSO(", 'F'}, + {"0VKSO1", 'F'}, + {"0VKSOF", 'F'}, + {"0VKSON", 'F'}, + {"0VKSOS", 'F'}, + {"0VKSOV", 'F'}, + {"0VKSU(", 'F'}, + {"0VKSUE", 'F'}, + {"0VKUE(", 'F'}, + {"0VKUE1", 'F'}, + {"0VKUEF", 'F'}, + {"0VKUEK", 'F'}, + {"0VKUEN", 'F'}, + {"0VKUES", 'F'}, + {"0VKUEV", 'F'}, + {"0VKV", 'F'}, + {"0VKV&(", 'F'}, + {"0VKV&1", 'F'}, + {"0VKV&F", 'F'}, + {"0VKV&N", 'F'}, + {"0VKV&S", 'F'}, + {"0VKV&V", 'F'}, + {"0VKV;", 'F'}, + {"0VKV;C", 'F'}, + {"0VKV;E", 'F'}, + {"0VKV;T", 'F'}, + {"0VKVB(", 'F'}, + {"0VKVB1", 'F'}, + {"0VKVBF", 'F'}, + {"0VKVBN", 'F'}, + {"0VKVBS", 'F'}, + {"0VKVBV", 'F'}, + {"0VKVC", 'F'}, + {"0VKVE(", 'F'}, + {"0VKVE1", 'F'}, + {"0VKVEF", 'F'}, + {"0VKVEK", 'F'}, + {"0VKVEN", 'F'}, + {"0VKVES", 'F'}, + {"0VKVEV", 'F'}, + {"0VKVO(", 'F'}, + {"0VKVOF", 'F'}, + {"0VKVOS", 'F'}, + {"0VKVU(", 'F'}, + {"0VKVUE", 'F'}, + {"0VO(((", 'F'}, + {"0VO((1", 'F'}, + {"0VO((E", 'F'}, + {"0VO((F", 'F'}, + {"0VO((N", 'F'}, + {"0VO((O", 'F'}, + {"0VO((S", 'F'}, + {"0VO((T", 'F'}, + {"0VO((V", 'F'}, + {"0VO(1&", 'F'}, + {"0VO(1)", 'F'}, + {"0VO(1,", 'F'}, + {"0VO(1O", 'F'}, + {"0VO(E(", 'F'}, + {"0VO(E1", 'F'}, + {"0VO(EE", 'F'}, + {"0VO(EF", 'F'}, + {"0VO(EK", 'F'}, + {"0VO(EN", 'F'}, + {"0VO(ES", 'F'}, + {"0VO(EV", 'F'}, + {"0VO(F(", 'F'}, + {"0VO(N&", 'F'}, + {"0VO(N)", 'F'}, + {"0VO(N,", 'F'}, + {"0VO(NO", 'F'}, + {"0VO(O(", 'F'}, + {"0VO(O1", 'F'}, + {"0VO(OF", 'F'}, + {"0VO(ON", 'F'}, + {"0VO(OS", 'F'}, + {"0VO(OV", 'F'}, + {"0VO(S&", 'F'}, + {"0VO(S)", 'F'}, + {"0VO(S,", 'F'}, + {"0VO(SO", 'F'}, + {"0VO(T(", 'F'}, + {"0VO(V&", 'F'}, + {"0VO(V)", 'F'}, + {"0VO(V,", 'F'}, + {"0VO(VO", 'F'}, + {"0VOF((", 'F'}, + {"0VOF()", 'F'}, + {"0VOF(1", 'F'}, + {"0VOF(E", 'F'}, + {"0VOF(F", 'F'}, + {"0VOF(N", 'F'}, + {"0VOF(S", 'F'}, + {"0VOF(V", 'F'}, + {"0VOK&(", 'F'}, + {"0VOK&1", 'F'}, + {"0VOK&F", 'F'}, + {"0VOK&N", 'F'}, + {"0VOK&S", 'F'}, + {"0VOK&V", 'F'}, + {"0VOK((", 'F'}, + {"0VOK(1", 'F'}, + {"0VOK(F", 'F'}, + {"0VOK(N", 'F'}, + {"0VOK(S", 'F'}, + {"0VOK(V", 'F'}, + {"0VOK1C", 'F'}, + {"0VOK1O", 'F'}, + {"0VOKF(", 'F'}, + {"0VOKNC", 'F'}, + {"0VOKO(", 'F'}, + {"0VOKO1", 'F'}, + {"0VOKOF", 'F'}, + {"0VOKON", 'F'}, + {"0VOKOS", 'F'}, + {"0VOKOV", 'F'}, + {"0VOKSC", 'F'}, + {"0VOKSO", 'F'}, + {"0VOKVC", 'F'}, + {"0VOKVO", 'F'}, + {"0VOS", 'F'}, + {"0VOS&(", 'F'}, + {"0VOS&1", 'F'}, + {"0VOS&E", 'F'}, + {"0VOS&F", 'F'}, + {"0VOS&K", 'F'}, + {"0VOS&N", 'F'}, + {"0VOS&S", 'F'}, + {"0VOS&U", 'F'}, + {"0VOS&V", 'F'}, + {"0VOS((", 'F'}, + {"0VOS(E", 'F'}, + {"0VOS(U", 'F'}, + {"0VOS)&", 'F'}, + {"0VOS))", 'F'}, + {"0VOS),", 'F'}, + {"0VOS);", 'F'}, + {"0VOS)B", 'F'}, + {"0VOS)E", 'F'}, + {"0VOS)K", 'F'}, + {"0VOS)O", 'F'}, + {"0VOS)U", 'F'}, + {"0VOS,(", 'F'}, + {"0VOS,F", 'F'}, + {"0VOS,V", 'F'}, + {"0VOS1(", 'F'}, + {"0VOS1F", 'F'}, + {"0VOS1N", 'F'}, + {"0VOS1O", 'F'}, + {"0VOS1S", 'F'}, + {"0VOS1U", 'F'}, + {"0VOS1V", 'F'}, + {"0VOS;", 'F'}, + {"0VOS;C", 'F'}, + {"0VOS;E", 'F'}, + {"0VOS;N", 'F'}, + {"0VOS;T", 'F'}, + {"0VOSA(", 'F'}, + {"0VOSAF", 'F'}, + {"0VOSAS", 'F'}, + {"0VOSAT", 'F'}, + {"0VOSAV", 'F'}, + {"0VOSB(", 'F'}, + {"0VOSB1", 'F'}, + {"0VOSBE", 'F'}, + {"0VOSBF", 'F'}, + {"0VOSBN", 'F'}, + {"0VOSBS", 'F'}, + {"0VOSBV", 'F'}, + {"0VOSC", 'F'}, + {"0VOSE(", 'F'}, + {"0VOSE1", 'F'}, + {"0VOSEF", 'F'}, + {"0VOSEK", 'F'}, + {"0VOSEN", 'F'}, + {"0VOSEO", 'F'}, + {"0VOSES", 'F'}, + {"0VOSEU", 'F'}, + {"0VOSEV", 'F'}, + {"0VOSF(", 'F'}, + {"0VOSK(", 'F'}, + {"0VOSK)", 'F'}, + {"0VOSK1", 'F'}, + {"0VOSKB", 'F'}, + {"0VOSKF", 'F'}, + {"0VOSKN", 'F'}, + {"0VOSKS", 'F'}, + {"0VOSKU", 'F'}, + {"0VOSKV", 'F'}, + {"0VOSO(", 'F'}, + {"0VOSO1", 'F'}, + {"0VOSOF", 'F'}, + {"0VOSOK", 'F'}, + {"0VOSON", 'F'}, + {"0VOSOS", 'F'}, + {"0VOSOT", 'F'}, + {"0VOSOU", 'F'}, + {"0VOSOV", 'F'}, + {"0VOSU", 'F'}, + {"0VOSU(", 'F'}, + {"0VOSU1", 'F'}, + {"0VOSU;", 'F'}, + {"0VOSUC", 'F'}, + {"0VOSUE", 'F'}, + {"0VOSUF", 'F'}, + {"0VOSUK", 'F'}, + {"0VOSUN", 'F'}, + {"0VOSUO", 'F'}, + {"0VOSUS", 'F'}, + {"0VOSUT", 'F'}, + {"0VOSUV", 'F'}, + {"0VOSV(", 'F'}, + {"0VOSVF", 'F'}, + {"0VOSVO", 'F'}, + {"0VOSVS", 'F'}, + {"0VOSVU", 'F'}, + {"0VOT((", 'F'}, + {"0VOT(1", 'F'}, + {"0VOT(F", 'F'}, + {"0VOT(N", 'F'}, + {"0VOT(S", 'F'}, + {"0VOT(V", 'F'}, + {"0VOU((", 'F'}, + {"0VOU(E", 'F'}, + {"0VOUEK", 'F'}, + {"0VOUEN", 'F'}, + {"0VU", 'F'}, + {"0VU(((", 'F'}, + {"0VU((1", 'F'}, + {"0VU((E", 'F'}, + {"0VU((F", 'F'}, + {"0VU((N", 'F'}, + {"0VU((S", 'F'}, + {"0VU((V", 'F'}, + {"0VU(1)", 'F'}, + {"0VU(1O", 'F'}, + {"0VU(E(", 'F'}, + {"0VU(E1", 'F'}, + {"0VU(EF", 'F'}, + {"0VU(EK", 'F'}, + {"0VU(EN", 'F'}, + {"0VU(ES", 'F'}, + {"0VU(EV", 'F'}, + {"0VU(F(", 'F'}, + {"0VU(N)", 'F'}, + {"0VU(NO", 'F'}, + {"0VU(S)", 'F'}, + {"0VU(SO", 'F'}, + {"0VU(V)", 'F'}, + {"0VU(VO", 'F'}, + {"0VU1,(", 'F'}, + {"0VU1,F", 'F'}, + {"0VU1,V", 'F'}, + {"0VU1C", 'F'}, + {"0VU1O(", 'F'}, + {"0VU1OF", 'F'}, + {"0VU1OS", 'F'}, + {"0VU1OV", 'F'}, + {"0VU;", 'F'}, + {"0VU;C", 'F'}, + {"0VUC", 'F'}, + {"0VUE", 'F'}, + {"0VUE((", 'F'}, + {"0VUE(1", 'F'}, + {"0VUE(E", 'F'}, + {"0VUE(F", 'F'}, + {"0VUE(N", 'F'}, + {"0VUE(O", 'F'}, + {"0VUE(S", 'F'}, + {"0VUE(V", 'F'}, + {"0VUE1", 'F'}, + {"0VUE1&", 'F'}, + {"0VUE1(", 'F'}, + {"0VUE1)", 'F'}, + {"0VUE1,", 'F'}, + {"0VUE1;", 'F'}, + {"0VUE1B", 'F'}, + {"0VUE1C", 'F'}, + {"0VUE1F", 'F'}, + {"0VUE1K", 'F'}, + {"0VUE1N", 'F'}, + {"0VUE1O", 'F'}, + {"0VUE1S", 'F'}, + {"0VUE1U", 'F'}, + {"0VUE1V", 'F'}, + {"0VUE;", 'F'}, + {"0VUE;C", 'F'}, + {"0VUEC", 'F'}, + {"0VUEF", 'F'}, + {"0VUEF(", 'F'}, + {"0VUEF,", 'F'}, + {"0VUEF;", 'F'}, + {"0VUEFC", 'F'}, + {"0VUEK", 'F'}, + {"0VUEK(", 'F'}, + {"0VUEK1", 'F'}, + {"0VUEK;", 'F'}, + {"0VUEKC", 'F'}, + {"0VUEKF", 'F'}, + {"0VUEKN", 'F'}, + {"0VUEKO", 'F'}, + {"0VUEKS", 'F'}, + {"0VUEKV", 'F'}, + {"0VUEN", 'F'}, + {"0VUEN&", 'F'}, + {"0VUEN(", 'F'}, + {"0VUEN)", 'F'}, + {"0VUEN,", 'F'}, + {"0VUEN1", 'F'}, + {"0VUEN;", 'F'}, + {"0VUENB", 'F'}, + {"0VUENC", 'F'}, + {"0VUENF", 'F'}, + {"0VUENK", 'F'}, + {"0VUENO", 'F'}, + {"0VUENS", 'F'}, + {"0VUENU", 'F'}, + {"0VUEOK", 'F'}, + {"0VUEON", 'F'}, + {"0VUEOO", 'F'}, + {"0VUES", 'F'}, + {"0VUES&", 'F'}, + {"0VUES(", 'F'}, + {"0VUES)", 'F'}, + {"0VUES,", 'F'}, + {"0VUES1", 'F'}, + {"0VUES;", 'F'}, + {"0VUESB", 'F'}, + {"0VUESC", 'F'}, + {"0VUESF", 'F'}, + {"0VUESK", 'F'}, + {"0VUESO", 'F'}, + {"0VUESU", 'F'}, + {"0VUESV", 'F'}, + {"0VUEV", 'F'}, + {"0VUEV&", 'F'}, + {"0VUEV(", 'F'}, + {"0VUEV)", 'F'}, + {"0VUEV,", 'F'}, + {"0VUEV;", 'F'}, + {"0VUEVB", 'F'}, + {"0VUEVC", 'F'}, + {"0VUEVF", 'F'}, + {"0VUEVK", 'F'}, + {"0VUEVN", 'F'}, + {"0VUEVO", 'F'}, + {"0VUEVS", 'F'}, + {"0VUEVU", 'F'}, + {"0VUF((", 'F'}, + {"0VUF()", 'F'}, + {"0VUF(1", 'F'}, + {"0VUF(F", 'F'}, + {"0VUF(N", 'F'}, + {"0VUF(S", 'F'}, + {"0VUF(V", 'F'}, + {"0VUK((", 'F'}, + {"0VUK(E", 'F'}, + {"0VUN((", 'F'}, + {"0VUN(1", 'F'}, + {"0VUN(F", 'F'}, + {"0VUN(S", 'F'}, + {"0VUN(V", 'F'}, + {"0VUN,(", 'F'}, + {"0VUN,F", 'F'}, + {"0VUN,V", 'F'}, + {"0VUN1(", 'F'}, + {"0VUN1,", 'F'}, + {"0VUN1O", 'F'}, + {"0VUNC", 'F'}, + {"0VUNE(", 'F'}, + {"0VUNE1", 'F'}, + {"0VUNEF", 'F'}, + {"0VUNEN", 'F'}, + {"0VUNES", 'F'}, + {"0VUNEV", 'F'}, + {"0VUNF(", 'F'}, + {"0VUNO(", 'F'}, + {"0VUNOF", 'F'}, + {"0VUNOS", 'F'}, + {"0VUNOV", 'F'}, + {"0VUNS(", 'F'}, + {"0VUNS,", 'F'}, + {"0VUNSO", 'F'}, + {"0VUO((", 'F'}, + {"0VUO(E", 'F'}, + {"0VUON(", 'F'}, + {"0VUON1", 'F'}, + {"0VUONF", 'F'}, + {"0VUONS", 'F'}, + {"0VUS,(", 'F'}, + {"0VUS,F", 'F'}, + {"0VUS,V", 'F'}, + {"0VUSC", 'F'}, + {"0VUSO(", 'F'}, + {"0VUSO1", 'F'}, + {"0VUSOF", 'F'}, + {"0VUSON", 'F'}, + {"0VUSOS", 'F'}, + {"0VUSOV", 'F'}, + {"0VUTN(", 'F'}, + {"0VUTN1", 'F'}, + {"0VUTNF", 'F'}, + {"0VUTNS", 'F'}, + {"0VUV,(", 'F'}, + {"0VUV,1", 'F'}, + {"0VUV,F", 'F'}, + {"0VUV,N", 'F'}, + {"0VUV,S", 'F'}, + {"0VUV,V", 'F'}, + {"0VUVC", 'F'}, + {"0VUVO(", 'F'}, + {"0VUVOF", 'F'}, + {"0VUVOS", 'F'}, + {"0X", 'F'}, + {"::", 'o'}, + {":=", 'o'}, + {"<<", 'o'}, + {"<=", 'o'}, + {"<>", 'o'}, + {"<@", 'o'}, + {">=", 'o'}, + {">>", 'o'}, + {"@>", 'o'}, + {"ABORT", 'k'}, + {"ABS", 'f'}, + {"ACCESSIBLE", 'k'}, + {"ACOS", 'f'}, + {"ADD", 'k'}, + {"ADDDATE", 'f'}, + {"ADDTIME", 'f'}, + {"AES_DECRYPT", 'f'}, + {"AES_ENCRYPT", 'f'}, + {"AGAINST", 'k'}, + {"AGE", 'f'}, + {"ALL_USERS", 'k'}, + {"ALTER", 'k'}, + {"ALTER DOMAIN", 'k'}, + {"ALTER TABLE", 'k'}, + {"ANALYZE", 'k'}, + {"AND", '&'}, + {"ANYARRAY", 't'}, + {"ANYELEMENT", 't'}, + {"ANYNONARRY", 't'}, + {"APPLOCK_MODE", 'f'}, + {"APPLOCK_TEST", 'f'}, + {"APP_NAME", 'f'}, + {"ARRAY_AGG", 'f'}, + {"ARRAY_CAT", 'f'}, + {"ARRAY_DIM", 'f'}, + {"ARRAY_FILL", 'f'}, + {"ARRAY_LENGTH", 'f'}, + {"ARRAY_LOWER", 'f'}, + {"ARRAY_NDIMS", 'f'}, + {"ARRAY_PREPEND", 'f'}, + {"ARRAY_TO_JSON", 'f'}, + {"ARRAY_TO_STRING", 'f'}, + {"ARRAY_UPPER", 'f'}, + {"AS", 'k'}, + {"ASC", 'k'}, + {"ASCII", 'f'}, + {"ASENSITIVE", 'k'}, + {"ASIN", 'f'}, + {"ASSEMBLYPROPERTY", 'f'}, + {"ASYMKEY_ID", 'f'}, + {"AT TIME", 'n'}, + {"AT TIME ZONE", 'k'}, + {"ATAN", 'f'}, + {"ATAN2", 'f'}, + {"AUTOINCREMENT", 'k'}, + {"AVG", 'f'}, + {"BEFORE", 'k'}, + {"BEGIN", 'T'}, + {"BENCHMARK", 'f'}, + {"BETWEEN", 'o'}, + {"BIGINT", 't'}, + {"BIGSERIAL", 't'}, + {"BIN", 'f'}, + {"BINARY", 't'}, + {"BINARY_DOUBLE_INFINITY", '1'}, + {"BINARY_DOUBLE_NAN", '1'}, + {"BINARY_FLOAT_INFINITY", '1'}, + {"BINARY_FLOAT_NAN", '1'}, + {"BINBINARY", 'f'}, + {"BIT_AND", 'f'}, + {"BIT_COUNT", 'f'}, + {"BIT_LENGTH", 'f'}, + {"BIT_OR", 'f'}, + {"BIT_XOR", 'f'}, + {"BLOB", 'k'}, + {"BOOLEAN", 't'}, + {"BOOL_AND", 'f'}, + {"BOOL_OR", 'f'}, + {"BOTH", 'k'}, + {"BTRIM", 'f'}, + {"BY", 'n'}, + {"BYTEA", 't'}, + {"CALL", 'T'}, + {"CASCADE", 'k'}, + {"CASE", 'E'}, + {"CAST", 'f'}, + {"CBOOL", 'f'}, + {"CBRT", 'f'}, + {"CBYTE", 'f'}, + {"CCUR", 'f'}, + {"CDATE", 'f'}, + {"CDBL", 'f'}, + {"CEIL", 'f'}, + {"CEILING", 'f'}, + {"CERTENCODED", 'f'}, + {"CERTPRIVATEKEY", 'f'}, + {"CERT_ID", 'f'}, + {"CERT_PROPERTY", 'f'}, + {"CHANGE", 'k'}, + {"CHANGES", 'f'}, + {"CHAR", 'f'}, + {"CHARACTER", 't'}, + {"CHARACTER VARYING", 't'}, + {"CHARACTER_LENGTH", 'f'}, + {"CHARINDEX", 'f'}, + {"CHARSET", 'f'}, + {"CHAR_LENGTH", 'f'}, + {"CHDIR", 'f'}, + {"CHDRIVE", 'f'}, + {"CHECK", 'k'}, + {"CHECKSUM_AGG", 'f'}, + {"CHOOSE", 'f'}, + {"CHR", 'f'}, + {"CINT", 'f'}, + {"CLNG", 'f'}, + {"CLOCK_TIMESTAMP", 'f'}, + {"COALESCE", 'f'}, + {"COERCIBILITY", 'f'}, + {"COLLATE", 'A'}, + {"COLLATION", 'f'}, + {"COLLATIONPROPERTY", 'f'}, + {"COLUMN", 'k'}, + {"COLUMNPROPERTY", 'f'}, + {"COLUMNS_UPDATED", 'f'}, + {"COL_LENGTH", 'f'}, + {"COL_NAME", 'f'}, + {"COMPRESS", 'f'}, + {"CONCAT", 'f'}, + {"CONCAT_WS", 'f'}, + {"CONDITION", 'k'}, + {"CONNECTION_ID", 'f'}, + {"CONSTRAINT", 'k'}, + {"CONTINUE", 'k'}, + {"CONV", 'f'}, + {"CONVERT", 'f'}, + {"CONVERT_FROM", 'f'}, + {"CONVERT_TO", 'f'}, + {"CONVERT_TZ", 'f'}, + {"COS", 'f'}, + {"COT", 'f'}, + {"COUNT", 'f'}, + {"COUNT_BIG", 'k'}, + {"CRC32", 'f'}, + {"CREATE", 'E'}, + {"CREATE OR", 'n'}, + {"CREATE OR REPLACE", 'T'}, + {"CROSS", 'n'}, + {"CROSS JOIN", 'k'}, + {"CSNG", 'f'}, + {"CSTRING", 't'}, + {"CTXSYS.DRITHSX.SN", 'f'}, + {"CUME_DIST", 'f'}, + {"CURDATE", 'f'}, + {"CURDIR", 'f'}, + {"CURRENT DATE", 'v'}, + {"CURRENT DEGREE", 'v'}, + {"CURRENT FUNCTION", 'v'}, + {"CURRENT FUNCTION PATH", 'v'}, + {"CURRENT PATH", 'v'}, + {"CURRENT SCHEMA", 'v'}, + {"CURRENT SERVER", 'v'}, + {"CURRENT TIME", 'v'}, + {"CURRENT TIMEZONE", 'v'}, + {"CURRENTUSER", 'f'}, + {"CURRENT_DATABASE", 'f'}, + {"CURRENT_DATE", 'v'}, + {"CURRENT_PATH", 'v'}, + {"CURRENT_QUERY", 'f'}, + {"CURRENT_SCHEMA", 'f'}, + {"CURRENT_SCHEMAS", 'f'}, + {"CURRENT_SERVER", 'v'}, + {"CURRENT_SETTING", 'f'}, + {"CURRENT_TIME", 'v'}, + {"CURRENT_TIMESTAMP", 'v'}, + {"CURRENT_TIMEZONE", 'v'}, + {"CURRENT_USER", 'v'}, + {"CURRVAL", 'f'}, + {"CURSOR", 'k'}, + {"CURSOR_STATUS", 'f'}, + {"CURTIME", 'f'}, + {"CVAR", 'f'}, + {"DATABASE", 'n'}, + {"DATABASEPROPERTYEX", 'f'}, + {"DATABASES", 'k'}, + {"DATABASE_PRINCIPAL_ID", 'f'}, + {"DATALENGTH", 'f'}, + {"DATE", 'f'}, + {"DATEADD", 'f'}, + {"DATEDIFF", 'f'}, + {"DATEFROMPARTS", 'f'}, + {"DATENAME", 'f'}, + {"DATEPART", 'f'}, + {"DATESERIAL", 'f'}, + {"DATETIME2FROMPARTS", 'f'}, + {"DATETIMEFROMPARTS", 'f'}, + {"DATETIMEOFFSETFROMPARTS", 'f'}, + {"DATEVALUE", 'f'}, + {"DATE_ADD", 'f'}, + {"DATE_FORMAT", 'f'}, + {"DATE_PART", 'f'}, + {"DATE_SUB", 'f'}, + {"DATE_TRUNC", 'f'}, + {"DAVG", 'f'}, + {"DAY", 'f'}, + {"DAYNAME", 'f'}, + {"DAYOFMONTH", 'f'}, + {"DAYOFWEEK", 'f'}, + {"DAYOFYEAR", 'f'}, + {"DAY_HOUR", 'k'}, + {"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", 't'}, + {"DECLARE", 'T'}, + {"DECODE", 'f'}, + {"DECRYPTBYASMKEY", 'f'}, + {"DECRYPTBYCERT", 'f'}, + {"DECRYPTBYKEY", 'f'}, + {"DECRYPTBYKEYAUTOCERT", 'f'}, + {"DECRYPTBYPASSPHRASE", 'f'}, + {"DEFAULT", 'k'}, + {"DEGREES", 'f'}, + {"DELAY", 'k'}, + {"DELAYED", 'k'}, + {"DELETE", 'T'}, + {"DENSE_RANK", 'f'}, + {"DESC", 'k'}, + {"DESCRIBE", 'k'}, + {"DES_DECRYPT", 'f'}, + {"DES_ENCRYPT", 'f'}, + {"DETERMINISTIC", 'k'}, + {"DFIRST", 'f'}, + {"DIFFERENCE", 'f'}, + {"DISTINCT", 'k'}, + {"DISTINCTROW", 'k'}, + {"DIV", 'o'}, + {"DLAST", 'f'}, + {"DLOOKUP", 'f'}, + {"DMAX", 'f'}, + {"DMIN", 'f'}, + {"DO", 'n'}, + {"DOUBLE", 't'}, + {"DOUBLE PRECISION", 't'}, + {"DROP", 'T'}, + {"DSUM", 'f'}, + {"DUAL", 'n'}, + {"EACH", 'k'}, + {"ELSE", 'k'}, + {"ELSEIF", 'k'}, + {"ELT", 'f'}, + {"ENCLOSED", 'k'}, + {"ENCODE", 'f'}, + {"ENCRYPT", 'f'}, + {"ENCRYPTBYASMKEY", 'f'}, + {"ENCRYPTBYCERT", 'f'}, + {"ENCRYPTBYKEY", 'f'}, + {"ENCRYPTBYPASSPHRASE", 'f'}, + {"ENUM_FIRST", 'f'}, + {"ENUM_LAST", 'f'}, + {"ENUM_RANGE", 'f'}, + {"EOMONTH", 'f'}, + {"EQV", 'o'}, + {"ESCAPED", 'k'}, + {"EVENTDATA", 'f'}, + {"EXCEPT", 'U'}, + {"EXEC", 'T'}, + {"EXECUTE", 'T'}, + {"EXECUTE AS", 'E'}, + {"EXECUTE AS LOGIN", 'E'}, + {"EXISTS", 'f'}, + {"EXIT", 'k'}, + {"EXP", 'f'}, + {"EXPLAIN", 'k'}, + {"EXPORT_SET", 'f'}, + {"EXTRACT", 'f'}, + {"EXTRACTVALUE", 'f'}, + {"EXTRACT_VALUE", 'f'}, + {"FALSE", '1'}, + {"FETCH", 'k'}, + {"FIELD", 'f'}, + {"FILEDATETIME", 'f'}, + {"FILEGROUPPROPERTY", 'f'}, + {"FILEGROUP_ID", 'f'}, + {"FILEGROUP_NAME", 'f'}, + {"FILELEN", 'f'}, + {"FILEPROPERTY", 'f'}, + {"FILE_ID", 'f'}, + {"FILE_IDEX", 'f'}, + {"FILE_NAME", 'f'}, + {"FIND_IN_SET", 'f'}, + {"FIRST_VALUE", 'f'}, + {"FLOAT", 't'}, + {"FLOAT4", 't'}, + {"FLOAT8", 't'}, + {"FLOOR", 'f'}, + {"FN_VIRTUALFILESTATS", 'f'}, + {"FOR", 'n'}, + {"FOR UPDATE", 'k'}, + {"FOR UPDATE NOWAIT", 'k'}, + {"FOR UPDATE OF", 'k'}, + {"FOR UPDATE SKIP", 'k'}, + {"FOR UPDATE SKIP LOCKED", 'k'}, + {"FOR UPDATE WAIT", 'k'}, + {"FORCE", 'k'}, + {"FOREIGN", 'k'}, + {"FORMAT", 'f'}, + {"FOUND_ROWS", 'f'}, + {"FROM", 'k'}, + {"FROM_DAYS", 'f'}, + {"FROM_UNIXTIME", 'f'}, + {"FULL OUTER", 'k'}, + {"FULL OUTER JOIN", 'k'}, + {"FULLTEXT", 'k'}, + {"FULLTEXTCATALOGPROPERTY", 'f'}, + {"FULLTEXTSERVICEPROPERTY", 'f'}, + {"FUNCTION", 'k'}, + {"GENERATE_SERIES", 'f'}, + {"GENERATE_SUBSCRIPTS", 'f'}, + {"GETATTR", 'f'}, + {"GETDATE", 'f'}, + {"GETUTCDATE", 'f'}, + {"GET_BIT", 'f'}, + {"GET_BYTE", 'f'}, + {"GET_FORMAT", 'f'}, + {"GET_LOCK", 'f'}, + {"GO", 'T'}, + {"GOTO", 'T'}, + {"GRANT", 'k'}, + {"GREATEST", 'f'}, + {"GROUP", 'n'}, + {"GROUP BY", 'B'}, + {"GROUPING", 'f'}, + {"GROUPING_ID", 'f'}, + {"GROUP_CONCAT", 'f'}, + {"HANDLER", 'T'}, + {"HASHBYTES", 'f'}, + {"HAS_PERMS_BY_NAME", 'f'}, + {"HAVING", 'B'}, + {"HEX", 'f'}, + {"HIGH_PRIORITY", 'k'}, + {"HOST_NAME", 'f'}, + {"HOUR", 'f'}, + {"HOUR_MICROSECOND", 'k'}, + {"HOUR_MINUTE", 'k'}, + {"HOUR_SECOND", 'k'}, + {"IDENTIFY", 'f'}, + {"IDENT_CURRENT", 'f'}, + {"IDENT_INCR", 'f'}, + {"IDENT_SEED", 'f'}, + {"IF", 'f'}, + {"IF EXISTS", 'f'}, + {"IFF", 'f'}, + {"IFNULL", 'f'}, + {"IGNORE", 'k'}, + {"IIF", 'f'}, + {"IN", 'k'}, + {"IN BOOLEAN", 'n'}, + {"IN BOOLEAN MODE", 'k'}, + {"INDEX", 'k'}, + {"INDEXKEY_PROPERTY", 'f'}, + {"INDEXPROPERTY", 'f'}, + {"INDEX_COL", 'f'}, + {"INET_ATON", 'f'}, + {"INET_NTOA", 'f'}, + {"INFILE", 'k'}, + {"INITCAP", 'f'}, + {"INNER", 'k'}, + {"INNER JOIN", 'k'}, + {"INOUT", 'k'}, + {"INSENSITIVE", 'k'}, + {"INSERT", 'E'}, + {"INSERT DELAYED", 'E'}, + {"INSERT DELAYED INTO", 'T'}, + {"INSERT HIGH_PRIORITY", 'E'}, + {"INSERT HIGH_PRIORITY INTO", 'T'}, + {"INSERT IGNORE", 'E'}, + {"INSERT IGNORE INTO", 'T'}, + {"INSERT INTO", 'T'}, + {"INSERT LOW_PRIORITY", 'E'}, + {"INSERT LOW_PRIORITY INTO", 'T'}, + {"INSTR", 'f'}, + {"INSTRREV", 'f'}, + {"INT", 't'}, + {"INT1", 't'}, + {"INT2", 't'}, + {"INT3", 't'}, + {"INT4", 't'}, + {"INT8", 't'}, + {"INTEGER", 't'}, + {"INTERSECT", 'U'}, + {"INTERSECT ALL", 'U'}, + {"INTERVAL", 'k'}, + {"INTO", 'k'}, + {"INTO DUMPFILE", 'k'}, + {"INTO OUTFILE", 'k'}, + {"IS", 'o'}, + {"IS DISTINCT", 'n'}, + {"IS DISTINCT FROM", 'o'}, + {"IS NOT", 'o'}, + {"IS NOT DISTINCT", 'n'}, + {"IS NOT DISTINCT FROM", 'o'}, + {"ISDATE", 'f'}, + {"ISEMPTY", 'f'}, + {"ISFINITE", 'f'}, + {"ISNULL", 'f'}, + {"ISNUMERIC", 'f'}, + {"IS_FREE_LOCK", 'f'}, + {"IS_MEMBER", 'f'}, + {"IS_OBJECTSIGNED", 'f'}, + {"IS_ROLEMEMBER", 'f'}, + {"IS_SRVROLEMEMBER", 'f'}, + {"IS_USED_LOCK", 'f'}, + {"ITERATE", 'k'}, + {"JOIN", 'k'}, + {"JULIANDAY", 'f'}, + {"JUSTIFY_DAYS", 'f'}, + {"JUSTIFY_HOURS", 'f'}, + {"JUSTIFY_INTERVAL", 'f'}, + {"KEYS", 'k'}, + {"KEY_GUID", 'f'}, + {"KEY_ID", 'f'}, + {"KILL", 'k'}, + {"LAG", 'f'}, + {"LASTVAL", 'f'}, + {"LAST_INSERT_ID", 'f'}, + {"LAST_INSERT_ROWID", 'f'}, + {"LAST_VALUE", 'f'}, + {"LCASE", 'f'}, + {"LEAD", 'f'}, + {"LEADING", 'k'}, + {"LEAST", 'f'}, + {"LEAVE", 'k'}, + {"LEFT", 'n'}, + {"LEFT JOIN", 'k'}, + {"LEFT OUTER", 'k'}, + {"LEFT OUTER JOIN", 'k'}, + {"LENGTH", 'f'}, + {"LIKE", 'o'}, + {"LIMIT", 'B'}, + {"LINEAR", 'k'}, + {"LINES", 'k'}, + {"LN", 'f'}, + {"LOAD", 'k'}, + {"LOAD DATA", 'T'}, + {"LOAD XML", 'T'}, + {"LOAD_EXTENSION", 'f'}, + {"LOAD_FILE", 'f'}, + {"LOCALTIME", 'v'}, + {"LOCALTIMESTAMP", 'v'}, + {"LOCATE", 'f'}, + {"LOCK", 'n'}, + {"LOCK IN", 'n'}, + {"LOCK IN SHARE", 'n'}, + {"LOCK IN SHARE MODE", 'k'}, + {"LOCK TABLE", 'k'}, + {"LOCK TABLES", 'k'}, + {"LOG", 'f'}, + {"LOG10", 'f'}, + {"LOG2", 'f'}, + {"LONGBLOB", 'k'}, + {"LONGTEXT", 'k'}, + {"LOOP", 'k'}, + {"LOWER", 'f'}, + {"LOWER_INC", 'f'}, + {"LOWER_INF", 'f'}, + {"LOW_PRIORITY", 'k'}, + {"LPAD", 'f'}, + {"LTRIM", 'f'}, + {"MAKEDATE", 'f'}, + {"MAKE_SET", 'f'}, + {"MASKLEN", 'f'}, + {"MASTER_BIND", 'k'}, + {"MASTER_POS_WAIT", 'f'}, + {"MASTER_SSL_VERIFY_SERVER_CERT", 'k'}, + {"MATCH", 'k'}, + {"MAX", 'f'}, + {"MAXVALUE", 'k'}, + {"MD5", 'f'}, + {"MEDIUMBLOB", 'k'}, + {"MEDIUMINT", 'k'}, + {"MEDIUMTEXT", 'k'}, + {"MERGE", 'k'}, + {"MICROSECOND", 'f'}, + {"MID", 'f'}, + {"MIDDLEINT", 'k'}, + {"MIN", 'f'}, + {"MINUTE", 'f'}, + {"MINUTE_MICROSECOND", 'k'}, + {"MINUTE_SECOND", 'k'}, + {"MKDIR", 'f'}, + {"MOD", 'o'}, + {"MODE", 'n'}, + {"MODIFIES", 'k'}, + {"MONEY", 't'}, + {"MONTH", 'f'}, + {"MONTHNAME", 'f'}, + {"NAME_CONST", 'f'}, + {"NATURAL", 'n'}, + {"NATURAL FULL", 'k'}, + {"NATURAL INNER", 'k'}, + {"NATURAL JOIN", 'k'}, + {"NATURAL LEFT", 'k'}, + {"NATURAL LEFT OUTER", 'k'}, + {"NATURAL LEFT OUTER JOIN", 'k'}, + {"NATURAL OUTER", 'k'}, + {"NATURAL RIGHT", 'k'}, + {"NETMASK", 'f'}, + {"NEXT VALUE", 'n'}, + {"NEXT VALUE FOR", 'k'}, + {"NEXTVAL", 'f'}, + {"NOT", 'o'}, + {"NOT BETWEEN", 'o'}, + {"NOT IN", 'k'}, + {"NOT LIKE", 'o'}, + {"NOT REGEXP", 'o'}, + {"NOT RLIKE", 'o'}, + {"NOT SIMILAR", 'o'}, + {"NOT SIMILAR TO", 'o'}, + {"NOTNULL", 'k'}, + {"NOW", 'f'}, + {"NOWAIT", 'k'}, + {"NO_WRITE_TO_BINLOG", 'k'}, + {"NTH_VALUE", 'f'}, + {"NTILE", 'f'}, + {"NULL", 'v'}, + {"NULLIF", 'f'}, + {"NUMERIC", 't'}, + {"NZ", 'f'}, + {"OBJECTPROPERTY", 'f'}, + {"OBJECTPROPERTYEX", 'f'}, + {"OBJECT_DEFINITION", 'f'}, + {"OBJECT_ID", 'f'}, + {"OBJECT_NAME", 'f'}, + {"OBJECT_SCHEMA_NAME", 'f'}, + {"OCT", 'f'}, + {"OCTET_LENGTH", 'f'}, + {"OFFSET", 'k'}, + {"OID", 't'}, + {"OLD_PASSWORD", 'f'}, + {"ONE_SHOT", 'k'}, + {"OPEN", 'k'}, + {"OPENDATASOURCE", 'f'}, + {"OPENQUERY", 'f'}, + {"OPENROWSET", 'f'}, + {"OPENXML", 'f'}, + {"OPTIMIZE", 'k'}, + {"OPTION", 'k'}, + {"OPTIONALLY", 'k'}, + {"OR", '&'}, + {"ORD", 'f'}, + {"ORDER", 'n'}, + {"ORDER BY", 'B'}, + {"ORIGINAL_DB_NAME", 'f'}, + {"ORIGINAL_LOGIN", 'f'}, + {"OUT", 'k'}, + {"OUTER", 'n'}, + {"OUTFILE", 'k'}, + {"OVERLAPS", 'f'}, + {"OVERLAY", 'f'}, + {"OWN3D", 'k'}, + {"OWN3D BY", 'B'}, + {"PARSENAME", 'f'}, + {"PARTITION", 'k'}, + {"PARTITION BY", 'B'}, + {"PASSWORD", 'n'}, + {"PATHINDEX", 'f'}, + {"PATINDEX", 'f'}, + {"PERCENTILE_COUNT", 'f'}, + {"PERCENTILE_DISC", 'f'}, + {"PERCENTILE_RANK", 'f'}, + {"PERCENT_RANK", 'f'}, + {"PERIOD_ADD", 'f'}, + {"PERIOD_DIFF", 'f'}, + {"PERMISSIONS", 'f'}, + {"PG_ADVISORY_LOCK", 'f'}, + {"PG_BACKEND_PID", 'f'}, + {"PG_CANCEL_BACKEND", 'f'}, + {"PG_CLIENT_ENCODING", 'f'}, + {"PG_CONF_LOAD_TIME", 'f'}, + {"PG_CREATE_RESTORE_POINT", 'f'}, + {"PG_HAS_ROLE", 'f'}, + {"PG_IS_IN_RECOVERY", 'f'}, + {"PG_IS_OTHER_TEMP_SCHEMA", 'f'}, + {"PG_LISTENING_CHANNELS", 'f'}, + {"PG_LS_DIR", 'f'}, + {"PG_MY_TEMP_SCHEMA", 'f'}, + {"PG_POSTMASTER_START_TIME", 'f'}, + {"PG_READ_BINARY_FILE", 'f'}, + {"PG_READ_FILE", 'f'}, + {"PG_RELOAD_CONF", 'f'}, + {"PG_ROTATE_LOGFILE", 'f'}, + {"PG_SLEEP", 'f'}, + {"PG_START_BACKUP", 'f'}, + {"PG_STAT_FILE", 'f'}, + {"PG_STOP_BACKUP", 'f'}, + {"PG_SWITCH_XLOG", 'f'}, + {"PG_TERMINATE_BACKEND", 'f'}, + {"PG_TRIGGER_DEPTH", 'f'}, + {"PI", 'f'}, + {"POSITION", 'f'}, + {"POW", 'f'}, + {"POWER", 'f'}, + {"PRECISION", 'k'}, + {"PREVIOUS VALUE", 'n'}, + {"PREVIOUS VALUE FOR", 'k'}, + {"PRIMARY", 'k'}, + {"PRINT", 'T'}, + {"PROCEDURE", 'k'}, + {"PROCEDURE ANALYSE", 'f'}, + {"PUBLISHINGSERVERNAME", 'f'}, + {"PURGE", 'k'}, + {"PWDCOMPARE", 'f'}, + {"PWDENCRYPT", 'f'}, + {"QUARTER", 'f'}, + {"QUOTE", 'f'}, + {"QUOTENAME", 'f'}, + {"QUOTE_IDENT", 'f'}, + {"QUOTE_LITERAL", 'f'}, + {"QUOTE_NULLABLE", 'f'}, + {"RADIANS", 'f'}, + {"RAISEERROR", 'E'}, + {"RAND", 'f'}, + {"RANDOM", 'f'}, + {"RANDOMBLOB", 'f'}, + {"RANGE", 'k'}, + {"RANK", 'f'}, + {"READ", 'k'}, + {"READ WRITE", 'k'}, + {"READS", 'k'}, + {"READ_WRITE", 'k'}, + {"REAL", 't'}, + {"REFERENCES", 'k'}, + {"REGCLASS", 't'}, + {"REGCONFIG", 't'}, + {"REGDICTIONARY", 't'}, + {"REGEXP", 'o'}, + {"REGEXP_MATCHES", 'f'}, + {"REGEXP_REPLACE", 'f'}, + {"REGEXP_SPLIT_TO_ARRAY", 'f'}, + {"REGEXP_SPLIT_TO_TABLE", 'f'}, + {"REGOPER", 't'}, + {"REGOPERATOR", 't'}, + {"REGPROC", 't'}, + {"REGPROCEDURE", 't'}, + {"REGTYPE", 't'}, + {"RELEASE", 'k'}, + {"RELEASE_LOCK", 'f'}, + {"RENAME", 'k'}, + {"REPEAT", 'k'}, + {"REPLACE", 'k'}, + {"REPLICATE", 'f'}, + {"REQUIRE", 'k'}, + {"RESIGNAL", 'k'}, + {"RESTRICT", 'k'}, + {"RETURN", 'k'}, + {"REVERSE", 'f'}, + {"REVOKE", 'k'}, + {"RIGHT", 'n'}, + {"RIGHT JOIN", 'k'}, + {"RIGHT OUTER", 'k'}, + {"RIGHT OUTER JOIN", 'k'}, + {"RLIKE", 'o'}, + {"ROUND", 'f'}, + {"ROW", 'f'}, + {"ROW_COUNT", 'f'}, + {"ROW_NUMBER", 'f'}, + {"ROW_TO_JSON", 'f'}, + {"RPAD", 'f'}, + {"RTRIM", 'f'}, + {"SCHAMA_NAME", 'f'}, + {"SCHEMA", 'k'}, + {"SCHEMAS", 'k'}, + {"SCHEMA_ID", 'f'}, + {"SCOPE_IDENTITY", 'f'}, + {"SECOND_MICROSECOND", 'k'}, + {"SEC_TO_TIME", 'f'}, + {"SELECT", 'E'}, + {"SELECT ALL", 'E'}, + {"SELECT DISTINCT", 'E'}, + {"SENSITIVE", 'k'}, + {"SEPARATOR", 'k'}, + {"SERIAL", 't'}, + {"SERIAL2", 't'}, + {"SERIAL4", 't'}, + {"SERIAL8", 't'}, + {"SERVERPROPERTY", 'f'}, + {"SESSION_USER", 'f'}, + {"SET", 'E'}, + {"SETATTR", 'f'}, + {"SETSEED", 'f'}, + {"SETVAL", 'f'}, + {"SET_BIT", 'f'}, + {"SET_BYTE", 'f'}, + {"SET_CONFIG", 'f'}, + {"SET_MASKLEN", 'f'}, + {"SHA", 'f'}, + {"SHA1", 'f'}, + {"SHA2", 'f'}, + {"SHOW", 'n'}, + {"SHUTDOWN", 'T'}, + {"SIGN", 'f'}, + {"SIGNAL", 'k'}, + {"SIGNBYASMKEY", 'f'}, + {"SIGNBYCERT", 'f'}, + {"SIMILAR", 'k'}, + {"SIMILAR TO", 'o'}, + {"SIN", 'f'}, + {"SLEEP", 'f'}, + {"SMALLDATETIMEFROMPARTS", 'f'}, + {"SMALLINT", 't'}, + {"SMALLSERIAL", 't'}, + {"SOUNDEX", 'f'}, + {"SOUNDS", 'o'}, + {"SOUNDS LIKE", 'o'}, + {"SPACE", 'f'}, + {"SPATIAL", 'k'}, + {"SPECIFIC", 'k'}, + {"SPLIT_PART", 'f'}, + {"SQL", 'k'}, + {"SQLEXCEPTION", 'k'}, + {"SQLSTATE", 'k'}, + {"SQLWARNING", 'k'}, + {"SQL_BIG_RESULT", 'k'}, + {"SQL_BUFFER_RESULT", 'k'}, + {"SQL_CACHE", 'k'}, + {"SQL_CALC_FOUND_ROWS", 'k'}, + {"SQL_NO_CACHE", 'k'}, + {"SQL_SMALL_RESULT", 'k'}, + {"SQL_VARIANT_PROPERTY", 'f'}, + {"SQRT", 'f'}, + {"SSL", 'k'}, + {"STARTING", 'k'}, + {"STATEMENT_TIMESTAMP", 'f'}, + {"STATS_DATE", 'f'}, + {"STDDEV", 'f'}, + {"STDDEV_POP", 'f'}, + {"STDDEV_SAMP", 'f'}, + {"STRAIGHT_JOIN", 'k'}, + {"STRCMP", 'f'}, + {"STRCOMP", 'f'}, + {"STRCONV", 'f'}, + {"STRING_AGG", 'f'}, + {"STRING_TO_ARRAY", 'f'}, + {"STRPOS", 'f'}, + {"STR_TO_DATE", 'f'}, + {"STUFF", 'f'}, + {"SUBDATE", 'f'}, + {"SUBSTR", 'f'}, + {"SUBSTRING", 'f'}, + {"SUBSTRING_INDEX", 'f'}, + {"SUBTIME", 'f'}, + {"SUM", 'f'}, + {"SUSER_ID", 'f'}, + {"SUSER_NAME", 'f'}, + {"SUSER_SID", 'f'}, + {"SUSER_SNAME", 'f'}, + {"SWITCHOFFET", 'f'}, + {"SYS.DATABASE_NAME", 'n'}, + {"SYS.FN_BUILTIN_PERMISSIONS", 'f'}, + {"SYS.FN_GET_AUDIT_FILE", 'f'}, + {"SYS.FN_MY_PERMISSIONS", 'f'}, + {"SYS.STRAGG", 'f'}, + {"SYSCOLUMNS", 'k'}, + {"SYSDATE", 'f'}, + {"SYSDATETIME", 'f'}, + {"SYSDATETIMEOFFSET", 'f'}, + {"SYSOBJECTS", 'k'}, + {"SYSTEM_USER", 'f'}, + {"SYSUSERS", 'k'}, + {"SYSUTCDATETME", 'f'}, + {"TABLE", 'k'}, + {"TAN", 'f'}, + {"TERMINATED", 'k'}, + {"TERTIARY_WEIGHTS", 'f'}, + {"TEXT", 't'}, + {"TEXTPOS", 'f'}, + {"TEXTPTR", 'f'}, + {"TEXTVALID", 'f'}, + {"THEN", 'k'}, + {"TIME", 'k'}, + {"TIMEDIFF", 'f'}, + {"TIMEFROMPARTS", 'f'}, + {"TIMEOFDAY", 'f'}, + {"TIMESERIAL", 'f'}, + {"TIMESTAMP", 't'}, + {"TIMESTAMPADD", 'f'}, + {"TIMEVALUE", 'f'}, + {"TIME_FORMAT", 'f'}, + {"TIME_TO_SEC", 'f'}, + {"TINYBLOB", 'k'}, + {"TINYINT", 'k'}, + {"TINYTEXT", 'k'}, + {"TODATETIMEOFFSET", 'f'}, + {"TOP", 'k'}, + {"TOTAL", 'f'}, + {"TOTAL_CHANGES", 'f'}, + {"TO_ASCII", 'f'}, + {"TO_CHAR", 'f'}, + {"TO_DATE", 'f'}, + {"TO_DAYS", 'f'}, + {"TO_HEX", 'f'}, + {"TO_NUMBER", 'f'}, + {"TO_SECONDS", 'f'}, + {"TO_TIMESTAMP", 'f'}, + {"TRAILING", 'n'}, + {"TRANSACTION_TIMESTAMP", 'f'}, + {"TRANSLATE", 'f'}, + {"TRIGGER", 'k'}, + {"TRIGGER_NESTLEVEL", 'f'}, + {"TRIM", 'f'}, + {"TRUE", '1'}, + {"TRUNC", 'f'}, + {"TRUNCATE", 'f'}, + {"TRY_CAST", 'f'}, + {"TRY_CONVERT", 'f'}, + {"TRY_PARSE", 'f'}, + {"TYPEOF", 'f'}, + {"TYPEPROPERTY", 'f'}, + {"TYPE_ID", 'f'}, + {"TYPE_NAME", 'f'}, + {"UCASE", 'f'}, + {"UESCAPE", 'o'}, + {"UNCOMPRESS", 'f'}, + {"UNCOMPRESS_LENGTH", 'f'}, + {"UNDO", 'k'}, + {"UNHEX", 'f'}, + {"UNICODE", 'f'}, + {"UNION", 'U'}, + {"UNION ALL", 'U'}, + {"UNION ALL DISTINCT", 'U'}, + {"UNION DISTINCT", 'U'}, + {"UNION DISTINCT ALL", 'U'}, + {"UNIQUE", 'n'}, + {"UNIX_TIMESTAMP", 'f'}, + {"UNI_ON", 'U'}, + {"UNKNOWN", 'v'}, + {"UNLOCK", 'k'}, + {"UNNEST", 'f'}, + {"UNSIGNED", 'k'}, + {"UPDATE", 'E'}, + {"UPDATEXML", 'f'}, + {"UPPER", 'f'}, + {"UPPER_INC", 'f'}, + {"UPPER_INF", 'f'}, + {"USAGE", 'k'}, + {"USE", 'T'}, + {"USER", 'n'}, + {"USER_ID", 'n'}, + {"USER_LOCK.SLEEP", 'f'}, + {"USER_NAME", 'n'}, + {"USING", 'f'}, + {"UTC_DATE", 'k'}, + {"UTC_TIME", 'k'}, + {"UTC_TIMESTAMP", 'k'}, + {"UTL_HTTP.REQUEST", 'f'}, + {"UTL_INADDR.GET_HOST_ADDRESS", 'f'}, + {"UTL_INADDR.GET_HOST_NAME", 'f'}, + {"UUID", 'f'}, + {"UUID_SHORT", 'f'}, + {"VALUES", 'k'}, + {"VAR", 'f'}, + {"VARBINARY", 'k'}, + {"VARCHAR", 't'}, + {"VARCHARACTER", 'k'}, + {"VARIANCE", 'f'}, + {"VARP", 'f'}, + {"VARYING", 'k'}, + {"VAR_POP", 'f'}, + {"VAR_SAMP", 'f'}, + {"VERIFYSIGNEDBYASMKEY", 'f'}, + {"VERIFYSIGNEDBYCERT", 'f'}, + {"VERSION", 'f'}, + {"VOID", 't'}, + {"WAIT", 'k'}, + {"WAITFOR", 'n'}, + {"WAITFOR DELAY", 'E'}, + {"WAITFOR RECEIVE", 'E'}, + {"WAITFOR TIME", 'E'}, + {"WEEK", 'f'}, + {"WEEKDAY", 'f'}, + {"WEEKDAYNAME", 'f'}, + {"WEEKOFYEAR", 'f'}, + {"WHEN", 'k'}, + {"WHERE", 'k'}, + {"WHILE", 'T'}, + {"WIDTH_BUCKET", 'f'}, + {"WITH", 'n'}, + {"WITH ROLLUP", 'k'}, + {"XMLAGG", 'f'}, + {"XMLCOMMENT", 'f'}, + {"XMLCONCAT", 'f'}, + {"XMLELEMENT", 'f'}, + {"XMLEXISTS", 'f'}, + {"XMLFOREST", 'f'}, + {"XMLFORMAT", 'f'}, + {"XMLPI", 'f'}, + {"XMLROOT", 'f'}, + {"XMLTYPE", 'f'}, + {"XML_IS_WELL_FORMED", 'f'}, + {"XOR", '&'}, + {"XPATH", 'f'}, + {"XPATH_EXISTS", 'f'}, + {"XP_EXECRESULTSET", 'k'}, + {"YEAR", 'f'}, + {"YEARWEEK", 'f'}, + {"YEAR_MONTH", 'k'}, + {"ZEROBLOB", 'f'}, + {"ZEROFILL", 'k'}, + {"^=", 'o'}, + {"_ARMSCII8", 't'}, + {"_ASCII", 't'}, + {"_BIG5", 't'}, + {"_BINARY", 't'}, + {"_CP1250", 't'}, + {"_CP1251", 't'}, + {"_CP1257", 't'}, + {"_CP850", 't'}, + {"_CP852", 't'}, + {"_CP866", 't'}, + {"_CP932", 't'}, + {"_DEC8", 't'}, + {"_EUCJPMS", 't'}, + {"_EUCKR", 't'}, + {"_GB2312", 't'}, + {"_GBK", 't'}, + {"_GEOSTD8", 't'}, + {"_GREEK", 't'}, + {"_HEBREW", 't'}, + {"_HP8", 't'}, + {"_KEYBCS2", 't'}, + {"_KOI8R", 't'}, + {"_KOI8U", 't'}, + {"_LATIN1", 't'}, + {"_LATIN2", 't'}, + {"_LATIN5", 't'}, + {"_LATIN7", 't'}, + {"_MACCE", 't'}, + {"_MACROMAN", 't'}, + {"_SJIS", 't'}, + {"_SWE7", 't'}, + {"_TIS620", 't'}, + {"_UJIS", 't'}, + {"_USC2", 't'}, + {"_UTF8", 't'}, + {"|/", 'o'}, + {"|=", 'o'}, + {"||", '&'}, + {"~*", 'o'}, +}; +static const size_t sql_keywords_sz = 10057; +#endif diff --git a/apache2/mod_security2.c b/apache2/mod_security2.c index 849ca9dc..6ad6b1a0 100644 --- a/apache2/mod_security2.c +++ b/apache2/mod_security2.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/mod_security2.exp b/apache2/mod_security2.exp new file mode 100644 index 00000000..0ab08b1e Binary files /dev/null and b/apache2/mod_security2.exp differ diff --git a/apache2/mod_security2.lib b/apache2/mod_security2.lib new file mode 100644 index 00000000..8d76f1fa Binary files /dev/null and b/apache2/mod_security2.lib differ diff --git a/apache2/mod_security2.obj b/apache2/mod_security2.obj new file mode 100644 index 00000000..a471f6e8 Binary files /dev/null and b/apache2/mod_security2.obj differ diff --git a/apache2/mod_security2.so b/apache2/mod_security2.so new file mode 100644 index 00000000..b574ed02 Binary files /dev/null and b/apache2/mod_security2.so differ diff --git a/apache2/modsecurity.c b/apache2/modsecurity.c index a7a5bb18..6b77132d 100644 --- a/apache2/modsecurity.c +++ b/apache2/modsecurity.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -391,11 +391,9 @@ apr_status_t modsecurity_tx_init(modsec_rec *msr) { if (msr->matched_vars == NULL) return -1; apr_table_clear(msr->matched_vars); - if(msr->txcfg->max_rule_time > 0) { - msr->perf_rules = apr_table_make(msr->mp, 8); - if (msr->perf_rules == NULL) return -1; - apr_table_clear(msr->perf_rules); - } + msr->perf_rules = apr_table_make(msr->mp, 8); + if (msr->perf_rules == NULL) return -1; + apr_table_clear(msr->perf_rules); /* Locate the cookie headers and parse them */ arr = apr_table_elts(msr->request_headers); diff --git a/apache2/modsecurity.h b/apache2/modsecurity.h index cb1a8d18..72cdea16 100644 --- a/apache2/modsecurity.h +++ b/apache2/modsecurity.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -442,6 +442,8 @@ struct modsec_rec { lua_State *L; #endif #endif + + int msc_sdbm_delete_error; }; struct directory_config { @@ -579,7 +581,7 @@ struct directory_config { /* Hash */ apr_array_header_t *hash_method; - const char *crypto_key; + const char *crypto_key; int crypto_key_len; const char *crypto_param_name; int hash_is_enabled; diff --git a/apache2/modsecurity.obj b/apache2/modsecurity.obj new file mode 100644 index 00000000..6884e172 Binary files /dev/null and b/apache2/modsecurity.obj differ diff --git a/apache2/msc_crypt.c b/apache2/msc_crypt.c index 5699c832..c7fd58e1 100644 --- a/apache2/msc_crypt.c +++ b/apache2/msc_crypt.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -68,10 +68,26 @@ char *normalize_path(modsec_rec *msr, char *input) { char *Uri = NULL; int bytes = 0; int i; + char *relative_link = NULL; + char *filename = NULL; + char *relative_path = NULL; + char *relative_uri = NULL; - xmlNormalizeURIPath(uri->path); - Uri = apr_pstrdup(msr->mp, uri->path); + filename = file_basename(msr->mp, msr->r->parsed_uri.path); + if(filename == NULL || (strlen(msr->r->parsed_uri.path) - strlen(filename) < 0)) + return NULL; + + relative_path = apr_pstrndup(msr->mp, msr->r->parsed_uri.path, strlen(msr->r->parsed_uri.path) - strlen(filename)); + relative_uri = apr_pstrcat(msr->mp, relative_path, uri->path, NULL); + + relative_link = apr_pstrdup(msr->mp, relative_uri); + + xmlNormalizeURIPath(relative_link); + + Uri = apr_pstrdup(msr->mp, relative_link); + +/* for(i = 0; i < (int)strlen(Uri); i++) { if(Uri[i] != '.' && Uri[i] != '/') { if (i - 1 < 0) @@ -88,12 +104,15 @@ char *normalize_path(modsec_rec *msr, char *input) { if(bytes >= (int)strlen(uri->path)) return NULL; +*/ + + content = apr_psprintf(msr->mp, "%s", Uri); - content = apr_psprintf(msr->mp, "%s", uri->path+bytes); if(parsed_content) parsed_content = apr_pstrcat(msr->mp, parsed_content, content, NULL); else parsed_content = apr_pstrcat(msr->mp, content, NULL); + } if(uri->query_raw) { @@ -629,6 +648,7 @@ int do_hash_method(modsec_rec *msr, char *link, int type) { int hash_response_body_links(modsec_rec *msr) { int lsize = 0, fsize = 0, lcount = 0, fcount = 0, i; int isize = 0, icount = 0, frsize = 0, frcount = 0; + int bytes = 0; xmlXPathContextPtr xpathCtx = NULL; xmlXPathObjectPtr xpathObj = NULL; xmlChar *content_option = NULL; @@ -687,6 +707,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link); lcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -703,6 +724,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "href", (const xmlChar *) mac_link); lcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -758,6 +780,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link); fcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -774,6 +797,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "action", (const xmlChar *) mac_link); fcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -828,6 +852,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link); icount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -844,6 +869,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link); icount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -893,6 +919,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link); frcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -909,6 +936,7 @@ int hash_response_body_links(modsec_rec *msr) { if(mac_link != NULL) { xmlSetProp(cur, (const xmlChar *) "src", (const xmlChar *) mac_link); frcount++; + bytes += strlen(mac_link); msr->of_stream_changed = 1; } mac_link = NULL; @@ -953,7 +981,7 @@ int hash_response_body_links(modsec_rec *msr) { if((elts >= INT32_MAX) || (elts < 0)) return 0; - return elts; + return bytes; obj_error: if(xpathCtx != NULL) @@ -1044,6 +1072,7 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) { } htmlDocContentDumpFormatOutput(output_buf, msr->crypto_html_tree, NULL, 0); + xmlOutputBufferFlush(output_buf); #ifdef LIBXML2_NEW_BUFFER @@ -1133,10 +1162,11 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) { } memset(msr->stream_output_data, 0x0, msr->stream_output_length+1); - memcpy(msr->stream_output_data, output_buf->buffer->content, msr->stream_output_length); + memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->buffer), msr->stream_output_length); + //memcpy(msr->stream_output_data, output_buf->buffer->content, msr->stream_output_length); if (msr->txcfg->debuglog_level >= 4) - msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%d] bytes.", output_buf->buffer->use); + msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONTENT to stream buffer [%d] bytes.", msr->stream_output_length); } else { @@ -1162,10 +1192,11 @@ int inject_hashed_response_body(modsec_rec *msr, int elts) { } memset(msr->stream_output_data, 0x0, msr->stream_output_length+1); - memcpy(msr->stream_output_data, output_buf->conv->content, msr->stream_output_length); + memcpy(msr->stream_output_data, (char *)xmlBufferContent(output_buf->conv), msr->stream_output_length); + //memcpy(msr->stream_output_data, output_buf->conv->content, msr->stream_output_length); if (msr->txcfg->debuglog_level >= 4) - msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%d] bytes.", output_buf->conv->use); + msr_log(msr, 4, "inject_hashed_response_body: Copying XML tree from CONV to stream buffer [%d] bytes.", msr->stream_output_length); } @@ -1209,14 +1240,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) { if(strlen(link) > 7 && strncmp("http:",(char*)link,5)==0){ path_chunk = strchr(link+7,'/'); if(path_chunk != NULL) { - if (msr->txcfg->debuglog_level >= 4) + if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Signing data [%s]", path_chunk+1); + } if(msr->txcfg->crypto_key_add == HASH_KEYONLY) hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1); if(msr->txcfg->crypto_key_add == HASH_SESSIONID) { - if(strlen(msr->sessionid) == 0) { + if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) { #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip); #else @@ -1251,14 +1283,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) { if(strlen(link) > 8 && strncmp("https",(char*)link,5)==0){ path_chunk = strchr(link+8,'/'); if(path_chunk != NULL) { - if (msr->txcfg->debuglog_level >= 4) + if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Signing data [%s]", path_chunk+1); + } if(msr->txcfg->crypto_key_add == HASH_KEYONLY) hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) path_chunk+1, strlen((char*)path_chunk)-1); if(msr->txcfg->crypto_key_add == HASH_SESSIONID) { - if(strlen(msr->sessionid) == 0) { + if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) { #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip); #else @@ -1291,14 +1324,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) { } } else if(*link=='/'){ - if (msr->txcfg->debuglog_level >= 4) + if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Signing data [%s]", link+1); + } if(msr->txcfg->crypto_key_add == HASH_KEYONLY) hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) link+1, strlen((char*)link)-1); if(msr->txcfg->crypto_key_add == HASH_SESSIONID) { - if(strlen(msr->sessionid) == 0) { + if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) { #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip); #else @@ -1344,14 +1378,15 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) { relative_link = relative_uri+1; - if (msr->txcfg->debuglog_level >= 4) + if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Signing data [%s] size %d", relative_link, strlen(relative_link)); + } if(msr->txcfg->crypto_key_add == HASH_KEYONLY) hash_value = hmac(msr, msr->txcfg->crypto_key, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link)); if(msr->txcfg->crypto_key_add == HASH_SESSIONID) { - if(strlen(msr->sessionid) == 0) { + if(msr->sessionid == NULL || strlen(msr->sessionid) == 0) { #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2 const char *new_pwd = apr_psprintf(msr->mp,"%s%s", msr->txcfg->crypto_key, msr->r->connection->client_ip); #else @@ -1379,6 +1414,9 @@ char *do_hash_link(modsec_rec *msr, char *link, int type) { msr->txcfg->crypto_key_len = strlen(new_pwd); hash_value = hmac(msr, new_pwd, msr->txcfg->crypto_key_len, (unsigned char *) relative_link, strlen((char*)relative_link)); } + + link = relative_uri; + } if(hash_value == NULL) return NULL; diff --git a/apache2/msc_crypt.h b/apache2/msc_crypt.h index 54a6dc7f..3b3aa6da 100644 --- a/apache2/msc_crypt.h +++ b/apache2/msc_crypt.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_crypt.obj b/apache2/msc_crypt.obj new file mode 100644 index 00000000..32f69fec Binary files /dev/null and b/apache2/msc_crypt.obj differ diff --git a/apache2/msc_geo.c b/apache2/msc_geo.c index 400dd904..49cf292c 100644 --- a/apache2/msc_geo.c +++ b/apache2/msc_geo.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_geo.h b/apache2/msc_geo.h index 8b64cb0d..12936146 100644 --- a/apache2/msc_geo.h +++ b/apache2/msc_geo.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_geo.obj b/apache2/msc_geo.obj new file mode 100644 index 00000000..cfd4112c Binary files /dev/null and b/apache2/msc_geo.obj differ diff --git a/apache2/msc_gsb.c b/apache2/msc_gsb.c index d3449e2f..49b1ff4e 100644 --- a/apache2/msc_gsb.c +++ b/apache2/msc_gsb.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_gsb.h b/apache2/msc_gsb.h index 7bff4c4a..87399d16 100644 --- a/apache2/msc_gsb.h +++ b/apache2/msc_gsb.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_gsb.obj b/apache2/msc_gsb.obj new file mode 100644 index 00000000..11457408 Binary files /dev/null and b/apache2/msc_gsb.obj differ diff --git a/apache2/msc_logging.c b/apache2/msc_logging.c index b2f2e445..66d204f7 100644 --- a/apache2/msc_logging.c +++ b/apache2/msc_logging.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_logging.h b/apache2/msc_logging.h index 308b09b6..75af9da7 100644 --- a/apache2/msc_logging.h +++ b/apache2/msc_logging.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_logging.obj b/apache2/msc_logging.obj new file mode 100644 index 00000000..c501dc52 Binary files /dev/null and b/apache2/msc_logging.obj differ diff --git a/apache2/msc_lua.c b/apache2/msc_lua.c index 6450e778..f4482ae7 100644 --- a/apache2/msc_lua.c +++ b/apache2/msc_lua.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_lua.h b/apache2/msc_lua.h index 1f8e50ee..a60697ce 100644 --- a/apache2/msc_lua.h +++ b/apache2/msc_lua.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_lua.obj b/apache2/msc_lua.obj new file mode 100644 index 00000000..c46386f9 Binary files /dev/null and b/apache2/msc_lua.obj differ diff --git a/apache2/msc_multipart.c b/apache2/msc_multipart.c index d0b3242b..4afd5c75 100644 --- a/apache2/msc_multipart.c +++ b/apache2/msc_multipart.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_multipart.h b/apache2/msc_multipart.h index fcc85a4c..a0f6a08d 100644 --- a/apache2/msc_multipart.h +++ b/apache2/msc_multipart.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_multipart.obj b/apache2/msc_multipart.obj new file mode 100644 index 00000000..e02bf817 Binary files /dev/null and b/apache2/msc_multipart.obj differ diff --git a/apache2/msc_parsers.c b/apache2/msc_parsers.c index ffa6d469..57f291ec 100644 --- a/apache2/msc_parsers.c +++ b/apache2/msc_parsers.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_parsers.h b/apache2/msc_parsers.h index 41a9e392..2be96dc6 100644 --- a/apache2/msc_parsers.h +++ b/apache2/msc_parsers.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_parsers.obj b/apache2/msc_parsers.obj new file mode 100644 index 00000000..d51b598d Binary files /dev/null and b/apache2/msc_parsers.obj differ diff --git a/apache2/msc_pcre.c b/apache2/msc_pcre.c index 3393493b..8534a209 100644 --- a/apache2/msc_pcre.c +++ b/apache2/msc_pcre.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_pcre.h b/apache2/msc_pcre.h index af581332..bbaa818b 100644 --- a/apache2/msc_pcre.h +++ b/apache2/msc_pcre.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_pcre.obj b/apache2/msc_pcre.obj new file mode 100644 index 00000000..a03bba23 Binary files /dev/null and b/apache2/msc_pcre.obj differ diff --git a/apache2/msc_release.c b/apache2/msc_release.c index 291c756b..4c06a8ce 100644 --- a/apache2/msc_release.c +++ b/apache2/msc_release.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_release.h b/apache2/msc_release.h index d87b185d..e3423712 100644 --- a/apache2/msc_release.h +++ b/apache2/msc_release.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -38,7 +38,7 @@ #define MODSEC_VERSION_MAJOR "2" #define MODSEC_VERSION_MINOR "7" -#define MODSEC_VERSION_MAINT "3" +#define MODSEC_VERSION_MAINT "5" #define MODSEC_VERSION_TYPE "" #define MODSEC_VERSION_RELEASE "" @@ -53,10 +53,10 @@ #define MODSEC_MODULE_NAME "ModSecurity for IIS (STABLE)" #else #ifdef VERSION_NGINX -#define MODSEC_MODULE_NAME "ModSecurity for nginx (RC)" +#define MODSEC_MODULE_NAME "ModSecurity for nginx (STABLE)" #else #ifdef VERSION_STANDALONE -#define MODSEC_MODULE_NAME "ModSecurity Standalone (RC)" +#define MODSEC_MODULE_NAME "ModSecurity Standalone (STABLE)" #else #define MODSEC_MODULE_NAME "ModSecurity for Apache" #endif diff --git a/apache2/msc_release.obj b/apache2/msc_release.obj new file mode 100644 index 00000000..bf638691 Binary files /dev/null and b/apache2/msc_release.obj differ diff --git a/apache2/msc_reqbody.c b/apache2/msc_reqbody.c index b76056ba..384e4578 100644 --- a/apache2/msc_reqbody.c +++ b/apache2/msc_reqbody.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -170,6 +170,7 @@ static apr_status_t modsecurity_request_body_store_memory(modsec_rec *msr, /* Would storing this chunk mean going over the limit? */ if ((msr->msc_reqbody_spilltodisk) + && (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_ON) && (msr->msc_reqbody_length + length > (apr_size_t)msr->txcfg->reqbody_inmemory_limit)) { msc_data_chunk **chunks; diff --git a/apache2/msc_reqbody.obj b/apache2/msc_reqbody.obj new file mode 100644 index 00000000..4676b4d2 Binary files /dev/null and b/apache2/msc_reqbody.obj differ diff --git a/apache2/msc_tree.c b/apache2/msc_tree.c index ec1da0d0..ce0e70af 100644 --- a/apache2/msc_tree.c +++ b/apache2/msc_tree.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ - * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_tree.h b/apache2/msc_tree.h index a6df488f..c82ffbc1 100644 --- a/apache2/msc_tree.h +++ b/apache2/msc_tree.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_tree.obj b/apache2/msc_tree.obj new file mode 100644 index 00000000..8ac388dc Binary files /dev/null and b/apache2/msc_tree.obj differ diff --git a/apache2/msc_unicode.c b/apache2/msc_unicode.c index 1090efcf..47d0d796 100644 --- a/apache2/msc_unicode.c +++ b/apache2/msc_unicode.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -130,8 +130,10 @@ static int unicode_map_create(directory_config *dcfg, char **error_msg) apr_file_close(u_map->map); - free(buf); - buf = NULL; + if(buf) { + free(buf); + buf = NULL; + } return 1; } diff --git a/apache2/msc_unicode.h b/apache2/msc_unicode.h index d37cbed5..1eaf3d66 100644 --- a/apache2/msc_unicode.h +++ b/apache2/msc_unicode.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_unicode.obj b/apache2/msc_unicode.obj new file mode 100644 index 00000000..3558c28c Binary files /dev/null and b/apache2/msc_unicode.obj differ diff --git a/apache2/msc_util.c b/apache2/msc_util.c index a4631221..23ae0375 100644 --- a/apache2/msc_util.c +++ b/apache2/msc_util.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -120,8 +120,13 @@ char *utf8_unicode_inplace_ex(apr_pool_t *mp, unsigned char *input, long int inp if ((c & 0x80) == 0) { /* single byte unicode (7 bit ASCII equivilent) has no validation */ count++; - if(count <= len) - *data++ = c; + if(count <= len) { + if(c == 0) + *data = x2c(&c); + else + *data++ = c; + } + } /* If first byte begins with binary 110 it is two byte encoding*/ else if ((c & 0xE0) == 0xC0) { diff --git a/apache2/msc_util.h b/apache2/msc_util.h index 06fa26c5..ea716d33 100644 --- a/apache2/msc_util.h +++ b/apache2/msc_util.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_util.obj b/apache2/msc_util.obj new file mode 100644 index 00000000..569c4df1 Binary files /dev/null and b/apache2/msc_util.obj differ diff --git a/apache2/msc_xml.c b/apache2/msc_xml.c index 87ab967e..a31decb5 100644 --- a/apache2/msc_xml.c +++ b/apache2/msc_xml.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_xml.h b/apache2/msc_xml.h index a3183212..f2390686 100644 --- a/apache2/msc_xml.h +++ b/apache2/msc_xml.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/msc_xml.obj b/apache2/msc_xml.obj new file mode 100644 index 00000000..85a57eb3 Binary files /dev/null and b/apache2/msc_xml.obj differ diff --git a/apache2/persist_dbm.c b/apache2/persist_dbm.c index 9b9536c8..b698e791 100644 --- a/apache2/persist_dbm.c +++ b/apache2/persist_dbm.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -220,6 +220,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec msr_log(msr, 1, "collection_retrieve_ex: Failed deleting collection (name \"%s\", " "key \"%s\"): %s", log_escape(msr->mp, col_name), log_escape_ex(msr->mp, col_key, col_key_len), get_apr_error(msr->mp, rc)); + msr->msc_sdbm_delete_error = 1; goto cleanup; } @@ -467,7 +468,7 @@ int collection_store(modsec_rec *msr, apr_table_t *col) { var->value = apr_psprintf(msr->mp, "%d", newval); var->value_len = strlen(var->value); - + if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "collection_store: Delta applied for %s.%s %d->%d (%d): %d + (%d) = %d [%s,%d]", log_escape_ex(msr->mp, var_name->value, var_name->value_len), @@ -490,7 +491,12 @@ int collection_store(modsec_rec *msr, apr_table_t *col) { /* Now generate the binary object. */ blob = apr_pcalloc(msr->mp, blob_size); if (blob == NULL) { - goto error; + if (dbm != NULL) { + apr_sdbm_unlock(dbm); + apr_sdbm_close(dbm); + } + + return -1; } blob[0] = 0x49; @@ -542,10 +548,16 @@ int collection_store(modsec_rec *msr, apr_table_t *col) { rc = apr_sdbm_store(dbm, key, value, APR_SDBM_REPLACE); if (rc != APR_SUCCESS) { msr_log(msr, 1, "collection_store: Failed to write to DBM file \"%s\": %s", dbm_filename, - get_apr_error(msr->mp, rc)); - goto error; + get_apr_error(msr->mp, rc)); + if (dbm != NULL) { + apr_sdbm_unlock(dbm); + apr_sdbm_close(dbm); + } + + return -1; } + apr_sdbm_unlock(dbm); apr_sdbm_close(dbm); if (msr->txcfg->debuglog_level >= 4) { @@ -557,11 +569,6 @@ int collection_store(modsec_rec *msr, apr_table_t *col) { return 0; error: - - if (dbm) { - apr_sdbm_close(dbm); - } - return -1; } @@ -672,9 +679,10 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) { msr_log(msr, 1, "collections_remove_stale: Failed deleting collection (name \"%s\", " "key \"%s\"): %s", log_escape(msr->mp, col_name), log_escape_ex(msr->mp, key.dptr, key.dsize - 1), get_apr_error(msr->mp, rc)); + msr->msc_sdbm_delete_error = 1; goto error; } - + if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "collections_remove_stale: Removed stale collection (name \"%s\", " "key \"%s\").", log_escape(msr->mp, col_name), diff --git a/apache2/persist_dbm.h b/apache2/persist_dbm.h index 2ad68e47..57d85bdd 100644 --- a/apache2/persist_dbm.h +++ b/apache2/persist_dbm.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/persist_dbm.obj b/apache2/persist_dbm.obj new file mode 100644 index 00000000..3647d6e2 Binary files /dev/null and b/apache2/persist_dbm.obj differ diff --git a/apache2/re.c b/apache2/re.c index 70956dbb..952a7867 100644 --- a/apache2/re.c +++ b/apache2/re.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -2604,12 +2604,16 @@ static int execute_operator(msre_var *var, msre_rule *rule, modsec_rec *msr, rt_time = apr_table_get(msr->perf_rules, rule->actionset->id); if(rt_time == NULL) { rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, (t1 - time_before_op)); - apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time); + rule_time = (apr_time_t)atoi(rt_time); + if(rule_time >= msr->txcfg->max_rule_time) + apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time); } else { rule_time = (apr_time_t)atoi(rt_time); rule_time += (t1 - time_before_op); - rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, rule_time); - apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time); + if(rule_time >= msr->txcfg->max_rule_time) { + rt_time = apr_psprintf(msr->mp, "%" APR_TIME_T_FMT, rule_time); + apr_table_setn(msr->perf_rules, rule->actionset->id, rt_time); + } } } } diff --git a/apache2/re.h b/apache2/re.h index c17aecd7..dec78067 100644 --- a/apache2/re.h +++ b/apache2/re.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re.obj b/apache2/re.obj new file mode 100644 index 00000000..1aa78599 Binary files /dev/null and b/apache2/re.obj differ diff --git a/apache2/re_actions.c b/apache2/re_actions.c index ca6d5905..6a5fbac6 100644 --- a/apache2/re_actions.c +++ b/apache2/re_actions.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -489,9 +489,27 @@ static apr_status_t msre_action_ver_init(msre_engine *engine, /* severity */ static apr_status_t msre_action_severity_init(msre_engine *engine, - msre_actionset *actionset, msre_action *action) + msre_actionset *actionset, msre_action *action) { - actionset->severity = atoi(action->param); + if (strcasecmp(action->param, "emergency") == 0) { + actionset->severity = 0; + } else if (strcasecmp(action->param, "alert") == 0) { + actionset->severity = 1; + } else if (strcasecmp(action->param, "critical") == 0) { + actionset->severity = 2; + } else if (strcasecmp(action->param, "error") == 0) { + actionset->severity = 3; + } else if (strcasecmp(action->param, "warning") == 0) { + actionset->severity = 4; + } else if (strcasecmp(action->param, "notice") == 0) { + actionset->severity = 5; + } else if (strcasecmp(action->param, "info") == 0) { + actionset->severity = 6; + } else if (strcasecmp(action->param, "debug") == 0) { + actionset->severity = 7; + } else { + actionset->severity = atoi(action->param); + } return 1; } diff --git a/apache2/re_actions.obj b/apache2/re_actions.obj new file mode 100644 index 00000000..001360bf Binary files /dev/null and b/apache2/re_actions.obj differ diff --git a/apache2/re_operators.c b/apache2/re_operators.c index 86b8c55e..7bd822c2 100644 --- a/apache2/re_operators.c +++ b/apache2/re_operators.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -27,6 +27,8 @@ #include #endif +#include "libinjection/libinjection.h" + /** * */ @@ -369,7 +371,7 @@ static int msre_op_ipmatchFromFile_execute(modsec_rec *msr, msre_rule *rule, msr /* rsub */ static char *param_remove_escape(msre_rule *rule, char *str, int len) { - char *parm = apr_palloc(rule->ruleset->mp, len); + char *parm = apr_pcalloc(rule->ruleset->mp, len); char *ret = parm; for(;*str!='\0';str++) { @@ -693,7 +695,7 @@ nextround: msr->of_stream_changed = 1; - strncpy(msr->stream_output_data, data, size); + memcpy(msr->stream_output_data, data, size); msr->stream_output_data[size] = '\0'; var->value_len = size; @@ -717,7 +719,7 @@ nextround: msr->if_stream_changed = 1; - strncpy(msr->stream_input_data, data, size); + memcpy(msr->stream_input_data, data, size); msr->stream_input_data[size] = '\0'; var->value_len = size; @@ -2129,6 +2131,41 @@ static int msre_op_contains_execute(modsec_rec *msr, msre_rule *rule, msre_var * return 0; } +/** libinjection detectSQLi + * links against files in libinjection directory + * See www.client9.com/libinjection for details + */ +static int msre_op_detectSQLi_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, + char **error_msg) { + + struct libinjection_sqli_state sqli_state; + int issqli; + int capture; + + libinjection_sqli_init(&sqli_state, var->value, var->value_len, 0); + issqli = libinjection_is_sqli(&sqli_state); + capture = apr_table_get(rule->actionset->actions, "capture") ? 1 : 0; + + if (issqli) { + set_match_to_tx(msr, capture, sqli_state.fingerprint, 0); + + *error_msg = apr_psprintf(msr->mp, "detected SQLi using libinjection with fingerprint '%s'", + sqli_state.fingerprint); + if (msr->txcfg->debuglog_level >= 9) { + msr_log(msr, 9, "ISSQL: libinjection fingerprint '%s' matched input '%s'", + sqli_state.fingerprint, + log_escape_ex(msr->mp, var->value, var->value_len)); + } + } else { + if (msr->txcfg->debuglog_level >= 9) { + msr_log(msr, 9, "ISSQL: not sqli, no libinjection sqli fingerprint matched input '%s'", + log_escape_ex(msr->mp, var->value, var->value_len)); + } + } + + return issqli; +} + /* containsWord */ static int msre_op_containsWord_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, char **error_msg) { @@ -4502,7 +4539,14 @@ void msre_engine_register_default_operators(msre_engine *engine) { msre_op_containsWord_execute ); - /* is */ + /* detectSQLi */ + msre_engine_op_register(engine, + "detectSQLi", + NULL, + msre_op_detectSQLi_execute + ); + + /* streq */ msre_engine_op_register(engine, "streq", NULL, /* ENH init function to flag var substitution */ diff --git a/apache2/re_operators.obj b/apache2/re_operators.obj new file mode 100644 index 00000000..135155b3 Binary files /dev/null and b/apache2/re_operators.obj differ diff --git a/apache2/re_tfns.c b/apache2/re_tfns.c index 133bfe23..63068dae 100644 --- a/apache2/re_tfns.c +++ b/apache2/re_tfns.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/apache2/re_tfns.obj b/apache2/re_tfns.obj new file mode 100644 index 00000000..1cf7b2a9 Binary files /dev/null and b/apache2/re_tfns.obj differ diff --git a/apache2/re_variables.c b/apache2/re_variables.c index f1dd0744..ce35bc1b 100644 --- a/apache2/re_variables.c +++ b/apache2/re_variables.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -511,6 +511,19 @@ static int var_reqbody_processor_generate(modsec_rec *msr, msre_var *var, msre_r return 1; } +/* SDBM_DELETE_ERROR */ +static int var_sdbm_delete_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule, + apr_table_t *vartab, apr_pool_t *mptmp) +{ + msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var)); + + rvar->value = apr_psprintf(mptmp, "%d", msr->msc_sdbm_delete_error); + rvar->value_len = strlen(rvar->value); + apr_table_addn(vartab, rvar->name, (void *)rvar); + + return 1; +} + /* REQBODY_ERROR */ static int var_reqbody_processor_error_generate(modsec_rec *msr, msre_var *var, msre_rule *rule, @@ -700,13 +713,22 @@ static int var_useragent_ip_generate(modsec_rec *msr, msre_var *var, msre_rule * static int var_remote_addr_generate(modsec_rec *msr, msre_var *var, msre_rule *rule, apr_table_t *vartab, apr_pool_t *mptmp) { +#if !defined(MSC_TEST) +#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 3 + if (ap_find_linked_module("mod_remoteip.c") != NULL) { + if(msr->r->useragent_ip != NULL) msr->remote_addr = apr_pstrdup(msr->mp, msr->r->useragent_ip); + return var_simple_generate(var, vartab, mptmp, msr->remote_addr); + } +#endif +#endif + return var_simple_generate(var, vartab, mptmp, msr->remote_addr); } /* REMOTE_HOST */ static int var_remote_host_generate(modsec_rec *msr, msre_var *var, msre_rule *rule, - apr_table_t *vartab, apr_pool_t *mptmp) + apr_table_t *vartab, apr_pool_t *mptmp) { const char *value1 = ap_get_remote_host(msr->r->connection, msr->r->per_dir_config, REMOTE_NAME, NULL); @@ -3117,6 +3139,16 @@ void msre_engine_register_default_variables(msre_engine *engine) { PHASE_REQUEST_HEADERS ); + msre_engine_variable_register(engine, + "SDBM_DELETE_ERROR", + VAR_SIMPLE, + 0, 0, + NULL, + var_sdbm_delete_error_generate, + VAR_DONT_CACHE, /* dynamic */ + PHASE_REQUEST_BODY + ); + /* REQBODY_PROCESSOR_ERROR - Deprecated */ msre_engine_variable_register(engine, "REQBODY_PROCESSOR_ERROR", diff --git a/apache2/re_variables.obj b/apache2/re_variables.obj new file mode 100644 index 00000000..7e3d4d82 Binary files /dev/null and b/apache2/re_variables.obj differ diff --git a/apache2/utf8tables.h b/apache2/utf8tables.h index 9b975868..28140ffa 100644 --- a/apache2/utf8tables.h +++ b/apache2/utf8tables.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/build/find_apr.m4 b/build/find_apr.m4 index a5324a64..5524b662 100644 --- a/build/find_apr.m4 +++ b/build/find_apr.m4 @@ -11,7 +11,8 @@ APR_CFLAGS="" APR_CPPFLAGS="" APR_LDFLAGS="" APR_LDADD="" - +APR_INCLUDEDIR="" +APR_LINKLD="" AC_DEFUN([CHECK_APR], [dnl @@ -63,6 +64,10 @@ if test -n "${apr_path}"; then if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDFLAGS: $APR_LDFLAGS); fi APR_LDADD="`${APR_CONFIG} --link-libtool`" if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDADD: $APR_LDADD); fi + APR_INCLUDEDIR="`${APR_CONFIG} --includedir`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr INCLUDEDIR: $APR_INCLUDEDIR); fi + APR_LINKLD="`${APR_CONFIG} --link-ld`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LINKLD: $APR_LINKLD); fi else AC_MSG_RESULT([no]) fi @@ -73,6 +78,8 @@ AC_SUBST(APR_CFLAGS) AC_SUBST(APR_CPPFLAGS) AC_SUBST(APR_LDFLAGS) AC_SUBST(APR_LDADD) +AC_SUBST(APR_INCLUDEDIR) +AC_SUBST(APR_LINKLD) if test -z "${APR_VERSION}"; then AC_MSG_NOTICE([*** apr library not found.]) diff --git a/build/find_apu.m4 b/build/find_apu.m4 index cf0b5936..bc82030b 100644 --- a/build/find_apu.m4 +++ b/build/find_apu.m4 @@ -10,6 +10,8 @@ APU_CONFIG="" APU_CFLAGS="" APU_LDFLAGS="" APU_LDADD="" +APU_INCLUDEDIR="" +APU_LINKLD="" AC_DEFUN([CHECK_APU], [dnl @@ -18,7 +20,7 @@ AC_ARG_WITH( apu, [AC_HELP_STRING([--with-apu=PATH],[Path to apu prefix or config script])], [test_paths="${with_apu}"], - [test_paths="/usr/local/libapr-util /usr/local/apr-util /usr/local/libapu /usr/local/apu /usr/local /opt/libapr-util /opt/apr-util /opt/libapu /opt/apu /opt /usr"]) + [test_paths="/usr/local/libapr-util /usr/local/apr-util /usr/local/libapu /usr/local/apu /usr/local/apr /usr/local /opt/libapr-util /opt/apr-util /opt/libapu /opt/apu /opt /usr"]) AC_MSG_CHECKING([for libapu config script]) @@ -60,6 +62,10 @@ if test -n "${apu_path}"; then if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDFLAGS: $APU_LDFLAGS); fi APU_LDADD="`${APU_CONFIG} --link-libtool`" if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDADD: $APU_LDADD); fi + APU_INCLUDEDIR="`${APU_CONFIG} --includedir`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu INCLUDEDIR: $APU_INCLUDEDIR); fi + APU_LINKLD="`${APU_CONFIG} --link-ld`" + if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LINKLD: $APU_LINKLD); fi else AC_MSG_RESULT([no]) fi @@ -69,6 +75,8 @@ AC_SUBST(APU_VERSION) AC_SUBST(APU_CFLAGS) AC_SUBST(APU_LDFLAGS) AC_SUBST(APU_LDADD) +AC_SUBST(APU_INCLUDEDIR) +AC_SUBST(APU_LINKLD) if test -z "${APU_VERSION}"; then AC_MSG_NOTICE([*** apu library not found.]) diff --git a/ext/mod_op_strstr.c b/ext/mod_op_strstr.c index cd4f298c..53c5138a 100644 --- a/ext/mod_op_strstr.c +++ b/ext/mod_op_strstr.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_reqbody_example.c b/ext/mod_reqbody_example.c index 133e320f..8b4abb60 100644 --- a/ext/mod_reqbody_example.c +++ b/ext/mod_reqbody_example.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_tfn_reverse.c b/ext/mod_tfn_reverse.c index 17048b66..1a5b8143 100644 --- a/ext/mod_tfn_reverse.c +++ b/ext/mod_tfn_reverse.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/ext/mod_var_remote_addr_port.c b/ext/mod_var_remote_addr_port.c index 0fda2553..4bd81ee9 100644 --- a/ext/mod_var_remote_addr_port.c +++ b/ext/mod_var_remote_addr_port.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/Makefile.win b/iis/Makefile.win index dafbacda..f352d930 100644 --- a/iis/Makefile.win +++ b/iis/Makefile.win @@ -52,6 +52,7 @@ OBJS1 = mod_security2.obj apache2_config.obj apache2_io.obj apache2_util.obj \ msc_release.obj msc_crypt.obj msc_tree.obj OBJS2 = api.obj buckets.obj config.obj filters.obj hooks.obj regex.obj server.obj OBJS3 = main.obj moduleconfig.obj mymodule.obj +OBJS4 = libinjection_sqli.obj all: $(DLL) @@ -60,14 +61,17 @@ dll: $(DLL) $(OBJS1): ..\apache2\$*.c $(CC) $(CFLAGS) -c ..\apache2\$*.c -Fo$@ +$(OBJS4): ..\apache2\libinjection\$*.c + $(CC) $(CFLAGS) -c ..\apache2\libinjection\$*.c -Fo$@ + $(OBJS2): ..\standalone\$*.c $(CC) $(CFLAGS) -c ..\standalone\$*.c -Fo$@ .cpp.obj: $(CC) $(CFLAGS) -c $< -Fo$@ -$(DLL): $(OBJS1) $(OBJS2) $(OBJS3) - $(LINK) $(LDFLAGS) $(OBJS1) $(OBJS2) $(OBJS3) $(LIBS) +$(DLL): $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) + $(LINK) $(LDFLAGS) $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(LIBS) IF EXIST $(DLL).manifest $(MT) -manifest $(DLL).manifest -outputresource:$(DLL);#1 clean: diff --git a/iis/main.cpp b/iis/main.cpp index f7ed1fe6..f761609a 100644 --- a/iis/main.cpp +++ b/iis/main.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/moduleconfig.cpp b/iis/moduleconfig.cpp index 53e6ba12..a92d51ff 100644 --- a/iis/moduleconfig.cpp +++ b/iis/moduleconfig.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/moduleconfig.h b/iis/moduleconfig.h index 70bae0ef..83b7517d 100644 --- a/iis/moduleconfig.h +++ b/iis/moduleconfig.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodule.cpp b/iis/mymodule.cpp index c2b63b41..9b8ce745 100644 --- a/iis/mymodule.cpp +++ b/iis/mymodule.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodule.h b/iis/mymodule.h index 9a53f4e6..efc11f98 100644 --- a/iis/mymodule.h +++ b/iis/mymodule.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/iis/mymodulefactory.h b/iis/mymodulefactory.h index 9934ab61..f8870da6 100644 --- a/iis/mymodulefactory.h +++ b/iis/mymodulefactory.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/java/Makefile.am b/java/Makefile.am index ae5a8dbe..9868044a 100644 --- a/java/Makefile.am +++ b/java/Makefile.am @@ -1,5 +1,9 @@ pkglibdir = $(prefix)/lib pkglib_LTLIBRARIES = libModSecurityJNI.la +#include_HEADERS = re.h modsecurity.h msc_logging.h msc_multipart.h \ +# msc_parsers.h msc_pcre.h msc_util.h msc_xml.h \ +# persist_dbm.h apache2.h msc_geo.h acmp.h utf8tables.h \ +# msc_lua.h msc_release.h libModSecurityJNI_la_SOURCES = ../apache2/mod_security2.c \ ../apache2/apache2_config.c ../apache2/apache2_io.c ../apache2/apache2_util.c \ @@ -7,19 +11,19 @@ libModSecurityJNI_la_SOURCES = ../apache2/mod_security2.c \ ../apache2/re_variables.c ../apache2/msc_logging.c ../apache2/msc_xml.c \ ../apache2/msc_multipart.c ../apache2/modsecurity.c ../apache2/msc_parsers.c \ ../apache2/msc_util.c ../apache2/msc_pcre.c ../apache2/persist_dbm.c ../apache2/msc_reqbody.c \ - ../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \ - ../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \ - ../apache2/msc_crypt.c ../apache2/msc_tree.c - ../standalone/api.c ../standalone/buckets.c \ - ../standalone/config.c ../standalone/filters.c \ - ../standalone/hooks.c ../standalone/regex.c ../standalone/server.c \ - org_modsecurity_ModSecurity.c + ../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \ + ../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \ + ../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/libinjection_sqli.c \ + ../standalone/api.c ../standalone/buckets.c \ + ../standalone/config.c ../standalone/filters.c \ + ../standalone/hooks.c ../standalone/regex.c ../standalone/server.c \ + org_modsecurity_ModSecurity.c libModSecurityJNI_la_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ - @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@ + @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@ -DVERSION_NGINX #libModSecurityJNI_la_CXXFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ # @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @LUA_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @CURL_CFLAGS@ -libModSecurityJNI_la_CPPFLAGS = @APR_CPPFLAGS@ @PCRE_CPPFLAGS@ @LIBXML2_CPPFLAGS@ @JNI_CPPFLAGS@ +libModSecurityJNI_la_CPPFLAGS = @APR_CPPFLAGS@ @PCRE_CPPFLAGS@ @LIBXML2_CPPFLAGS@ @JNI_CPPFLAGS@ @STANDALONE_CPPFLAGS@ libModSecurityJNI_la_LIBADD = @APR_LDADD@ @APU_LDADD@ @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@ if AIX diff --git a/java/ModSecurityJNI.vcxproj b/java/ModSecurityJNI.vcxproj index d25bd911..7919fdfd 100644 --- a/java/ModSecurityJNI.vcxproj +++ b/java/ModSecurityJNI.vcxproj @@ -71,7 +71,7 @@ Level3 Disabled - ..\standalone;c:\Program Files (x86)\Java\jdk1.7.0_21\include\win32;c:\Program Files (x86)\Java\jdk1.7.0_21\include;C:\work\pcre-8.30\include;C:\work\pcre-8.30;C:\work\libxml2-2.7.7\include;C:\apache22\include;..\apache2;c:\work\httpd-2.2.24\include + ..\standalone;c:\Program Files (x86)\Java\jdk1.7.0_21\include\win32;c:\Program Files (x86)\Java\jdk1.7.0_21\include;C:\work\pcre-8.30\include;C:\work\pcre-8.30;C:\work\libxml2-2.7.7\include;C:\apache22\include;..\apache2;..\apache\libinjection\;c:\work\httpd-2.2.24\include _MBCS;%(PreprocessorDefinitions);WIN32;WINNT;inline=APR_INLINE;AP_DECLARE_STATIC;VERSION_STANDALONE 4244;4018 diff --git a/java/ModSecurityLoader/dist/ModSecurityLoader.jar b/java/ModSecurityLoader/dist/ModSecurityLoader.jar index 760dcf1b..867a2714 100644 Binary files a/java/ModSecurityLoader/dist/ModSecurityLoader.jar and b/java/ModSecurityLoader/dist/ModSecurityLoader.jar differ diff --git a/java/ModSecurityLoader/src/org/modsecurity/loader/ModSecurityLoader.java b/java/ModSecurityLoader/src/org/modsecurity/loader/ModSecurityLoader.java index 12465a6d..23e5d534 100644 --- a/java/ModSecurityLoader/src/org/modsecurity/loader/ModSecurityLoader.java +++ b/java/ModSecurityLoader/src/org/modsecurity/loader/ModSecurityLoader.java @@ -46,7 +46,7 @@ public class ModSecurityLoader { } } - public void main(String[] args) { + public static void main(String[] args) { } } diff --git a/java/ModSecurityTestApp/dist/ModSecurityTestApp.war b/java/ModSecurityTestApp/dist/ModSecurityTestApp.war new file mode 100644 index 00000000..673092da Binary files /dev/null and b/java/ModSecurityTestApp/dist/ModSecurityTestApp.war differ diff --git a/java/ModSecurityTestApp/src/java/org/modsecurity/ModSecurity.java b/java/ModSecurityTestApp/src/java/org/modsecurity/ModSecurity.java index 506bf0c4..3456062a 100644 --- a/java/ModSecurityTestApp/src/java/org/modsecurity/ModSecurity.java +++ b/java/ModSecurityTestApp/src/java/org/modsecurity/ModSecurity.java @@ -22,7 +22,6 @@ public final class ModSecurity { //ModSecurityLoader calls System.load() for every native library needed by ModSecurity. // try { // Class.forName("org.modsecurity.loader.ModSecurityLoader"); -// System.out.println("ModSecurity libraries loaded."); // } catch (ClassNotFoundException ex) { // java.util.logging.Logger.getLogger(ModSecurity.class.getName()).log(java.util.logging.Level.SEVERE, // "ModSecurityLoader was not found, please make sure that you have \"ModSecurityLoader.jar\" in your server lib folder.", ex); @@ -30,13 +29,6 @@ public final class ModSecurity { //If the ModSecurityLoader is not used, native libraries can be loaded here, however this is bad practice since this will raise UnsatisfiedLinkError if //ModSecurity is used in multiple webapps. This will also will raise problems when the web-app is redeployed and the server is running. -// System.load("c:\\work\\mod_security\\java\\libs\\zlib1.dll"); -// System.load("c:\\work\\mod_security\\java\\libs\\libxml2.dll"); -// System.load("c:\\work\\mod_security\\java\\libs\\pcre.dll"); -// System.load("c:\\work\\mod_security\\java\\libs\\libapr-1.dll"); -// System.load("c:\\work\\mod_security\\java\\libs\\libapriconv-1.dll"); -// System.load("c:\\work\\mod_security\\java\\libs\\libaprutil-1.dll"); -// System.load("c:\\work\\mod_security\\java\\Debug\\ModSecurityJNI.dll"); try { System.loadLibrary("zlib1"); //needed for libxml2 in Windows } catch(UnsatisfiedLinkError ex) { @@ -45,11 +37,20 @@ public final class ModSecurity { System.loadLibrary("pcre"); System.loadLibrary("libapr-1"); try { - System.loadLibrary("libapriconv-1"); - } catch(UnsatisfiedLinkError ex) { //needed for libaprutil-1 in Windows + System.loadLibrary("libapriconv-1"); //needed for libaprutil-1 in Windows + } catch(UnsatisfiedLinkError ex) { } System.loadLibrary("libaprutil-1"); System.loadLibrary("ModSecurityJNI"); + //System.loadLibrary tries to resolve native libraries from java.library.path variable. If this fails, absolute path to libraries + //can be specified using System.load("/path/lib.so") +// try { System.load("c:\\work\\mod_security\\java\\libs\\zlib1.dll"); } catch(UnsatisfiedLinkError ex) {} +// System.load("c:\\work\\mod_security\\java\\libs\\libxml2.dll"); +// System.load("c:\\work\\mod_security\\java\\libs\\pcre.dll"); +// System.load("c:\\work\\mod_security\\java\\libs\\libapr-1.dll"); +// try { System.load("c:\\work\\mod_security\\java\\libs\\libapriconv-1.dll"); } catch(UnsatisfiedLinkError ex) {} +// System.load("c:\\work\\mod_security\\java\\libs\\libaprutil-1.dll"); +// System.load("c:\\work\\mod_security\\java\\Debug\\ModSecurityJNI.dll"); } public ModSecurity(FilterConfig fc, String confFile) throws ServletException { diff --git a/java/org_modsecurity_ModSecurity.c b/java/org_modsecurity_ModSecurity.c index 64d8865a..4ef9932a 100644 --- a/java/org_modsecurity_ModSecurity.c +++ b/java/org_modsecurity_ModSecurity.c @@ -214,8 +214,14 @@ void logSec(void *obj, int level, char *str) apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos) { - jobject inputStream = getJavaServletContext(r, JAVASERVLET_INSTREAM); //servlet request input stream JNIEnv *env; + jclass inputStreamClass; + jmethodID read; + jbyteArray byteArrayBuf; + jint count; + jbyte *bufferPtr; + jobject inputStream = getJavaServletContext(r, JAVASERVLET_INSTREAM); //servlet request input stream + *readcnt = 0; @@ -228,13 +234,13 @@ apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, un if (!(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL)) { //read request body from the servlet input stream using 'read' method - jclass inputStreamClass = (*env)->FindClass(env, SERVLETINPUTSTREAM_JAVACLASS); - jmethodID read = (*env)->GetMethodID(env, inputStreamClass, INPUTSTREAM_READ_MET, INPUTSTREAM_READ_SIG); + inputStreamClass = (*env)->FindClass(env, SERVLETINPUTSTREAM_JAVACLASS); + read = (*env)->GetMethodID(env, inputStreamClass, INPUTSTREAM_READ_MET, INPUTSTREAM_READ_SIG); - jbyteArray byteArrayBuf = (*env)->NewByteArray(env, length); + byteArrayBuf = (*env)->NewByteArray(env, length); - jint count = (*env)->CallIntMethod(env, inputStream, read, byteArrayBuf, 0, length); - jbyte* bufferPtr = (*env)->GetByteArrayElements(env, byteArrayBuf, NULL); + count = (*env)->CallIntMethod(env, inputStream, read, byteArrayBuf, 0, length); + bufferPtr = (*env)->GetByteArrayElements(env, byteArrayBuf, NULL); if (count == -1 || count > length || (*env)->ExceptionCheck(env) == JNI_TRUE) //end of stream { diff --git a/mlogc/mlogc-batch-load.pl.in b/mlogc/mlogc-batch-load.pl.in index 662df3db..53da8786 100755 --- a/mlogc/mlogc-batch-load.pl.in +++ b/mlogc/mlogc-batch-load.pl.in @@ -1,7 +1,7 @@ #!@PERL@ # # ModSecurity for Apache 2.x, http://www.modsecurity.org/ -# Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +# Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) # # You may not use this file except in compliance with # the License.  You may obtain a copy of the License at diff --git a/mlogc/mlogc.c b/mlogc/mlogc.c index edb5b962..41632309 100644 --- a/mlogc/mlogc.c +++ b/mlogc/mlogc.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/nginx/modsecurity/apr_bucket_nginx.c b/nginx/modsecurity/apr_bucket_nginx.c index 7b41b6f0..62eb59a7 100644 --- a/nginx/modsecurity/apr_bucket_nginx.c +++ b/nginx/modsecurity/apr_bucket_nginx.c @@ -204,6 +204,17 @@ move_brigade_to_chain(apr_bucket_brigade *bb, ngx_chain_t **ll, ngx_pool_t *pool if (APR_BUCKET_IS_EOS(e)) { if (cl == NULL) { + cl = ngx_alloc_chain_link(pool); + if (cl == NULL) { + break; + } + + cl->buf = ngx_calloc_buf(pool); + if (cl->buf == NULL) { + break; + } + + cl->buf->last_buf = 1; *ll = cl; } else { cl->buf->last_buf = 1; diff --git a/nginx/modsecurity/config b/nginx/modsecurity/config index dbf42706..a77538ba 100644 --- a/nginx/modsecurity/config +++ b/nginx/modsecurity/config @@ -3,5 +3,5 @@ CORE_MODULES="$CORE_MODULES ngx_pool_context_module" HTTP_AUX_FILTER_MODULES="ngx_http_modsecurity $HTTP_AUX_FILTER_MODULES" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_modsecurity.c $ngx_addon_dir/apr_bucket_nginx.c $ngx_addon_dir/ngx_pool_context.c" NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/apr_bucket_nginx.h $ngx_addon_dir/ngx_pool_context.h" -CORE_LIBS="$CORE_LIBS $ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm " -CORE_INCS="$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 $ngx_addon_dir $ngx_addon_dir/../../standalone $ngx_addon_dir/../../apache2 /usr/include/libxml2 " +CORE_LIBS="$CORE_LIBS $ngx_addon_dir/../../standalone/.libs/standalone.a -L/usr/local/apr/lib -lapr-1 -L/usr/local/apr/lib -laprutil-1 -lpcre -lxml2 -lz -lm -ldl " +CORE_INCS="$CORE_INCS $ngx_addon_dir $ngx_addon_dir/../../standalone $ngx_addon_dir/../../apache2 /usr/include/libxml2 /usr/local/apache2/include /usr/local/apr/include/apr-1 /usr/local/apr/include/apr-1" diff --git a/nginx/modsecurity/ngx_http_modsecurity.c b/nginx/modsecurity/ngx_http_modsecurity.c index 83edd42b..26112a67 100644 --- a/nginx/modsecurity/ngx_http_modsecurity.c +++ b/nginx/modsecurity/ngx_http_modsecurity.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -16,6 +16,8 @@ #include #include +#include + #undef CR #undef LF #undef CRLF @@ -52,7 +54,6 @@ static ngx_int_t ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_cha static ngx_int_t ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf); static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf); static ngx_int_t ngx_http_modsecurity_init_process(ngx_cycle_t *cycle); -static void ngx_http_modsecurity_exit_process(ngx_cycle_t *cycle); static void *ngx_http_modsecurity_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_modsecurity_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); static char *ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -60,6 +61,7 @@ static char *ngx_http_modsecurity_enable(ngx_conf_t *cf, ngx_command_t *cmd, voi static ngx_http_modsecurity_ctx_t * ngx_http_modsecurity_create_ctx(ngx_http_request_t *r); static int ngx_http_modsecurity_drop_action(request_rec *r); +static void ngx_http_modsecurity_terminate(ngx_cycle_t *cycle); static void ngx_http_modsecurity_cleanup(void *data); static int ngx_http_modsecurity_save_headers_in_visitor(void *data, const char *key, const char *value); @@ -113,8 +115,8 @@ ngx_module_t ngx_http_modsecurity = { ngx_http_modsecurity_init_process, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ - ngx_http_modsecurity_exit_process, /* exit process */ - ngx_http_modsecurity_exit_process, /* exit master */ + ngx_http_modsecurity_terminate, /* exit process */ + ngx_http_modsecurity_terminate, /* exit master */ NGX_MODULE_V1_PADDING }; @@ -156,7 +158,8 @@ ngx_pstrdup0(ngx_pool_t *pool, ngx_str_t *src) } -static inline int ngx_http_modsecurity_method_number(unsigned int nginx) +static inline int +ngx_http_modsecurity_method_number(unsigned int nginx) { /* * http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup @@ -246,7 +249,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r) } #endif - req->parsed_uri.path = req->path_info; + req->parsed_uri.path = (char *)ngx_pstrdup0(r->pool, &r->uri); req->parsed_uri.is_initialized = 1; str.data = r->port_start; @@ -254,7 +257,7 @@ ngx_http_modsecurity_load_request(ngx_http_request_t *r) req->parsed_uri.port = ngx_atoi(str.data, str.len); req->parsed_uri.port_str = (char *)ngx_pstrdup0(r->pool, &str); - req->parsed_uri.query = req->args; + req->parsed_uri.query = r->args.len ? req->args : NULL; req->parsed_uri.dns_looked_up = 0; req->parsed_uri.dns_resolved = 0; @@ -786,6 +789,29 @@ ngx_http_modsecurity_save_headers_out_visitor(void *data, const char *key, const return 1; } + +static ngx_inline ngx_int_t +ngx_http_modsecurity_status(ngx_http_request_t *r, int status) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: status %d", status); + + if (status == DECLINED || status == APR_SUCCESS) { + return NGX_DECLINED; + } + + /* nginx known status */ + if ( (status >= 300 && status < 308) /* 3XX */ + || (status >= 400 && status < 417) /* 4XX */ + || (status >= 500 && status < 508) /* 5XX */ + || (status == NGX_HTTP_CREATED || status == NGX_HTTP_NO_CONTENT) ) { + + return status; + } + + return NGX_HTTP_INTERNAL_SERVER_ERROR; +} + + /* create loc conf struct */ static void * ngx_http_modsecurity_create_loc_conf(ngx_conf_t *cf) @@ -855,11 +881,11 @@ modsec_pcre_free(void *ptr) { } +static server_rec *modsec_server = NULL; + static ngx_int_t ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf) { - server_rec *s; - /* XXX: temporary hack, nginx uses pcre as well and hijacks these two */ pcre_malloc = modsec_pcre_malloc; pcre_free = modsec_pcre_free; @@ -868,24 +894,33 @@ ngx_http_modsecurity_preconfiguration(ngx_conf_t *cf) modsecSetDropAction(ngx_http_modsecurity_drop_action); /* TODO: server_rec per server conf */ - s = modsecInit(); - if (s == NULL) { + modsec_server = modsecInit(); + if (modsec_server == NULL) { return NGX_ERROR; } /* set host name */ - s->server_hostname = ngx_palloc(cf->pool, ngx_cycle->hostname.len + 1); - if (s->server_hostname == NULL) { + modsec_server->server_hostname = ngx_palloc(cf->pool, ngx_cycle->hostname.len + 1); + if (modsec_server->server_hostname == NULL) { return NGX_ERROR; } - ngx_memcpy(s->server_hostname, ngx_cycle->hostname.data, ngx_cycle->hostname.len); - s->server_hostname[ ngx_cycle->hostname.len] = '\0'; + ngx_memcpy(modsec_server->server_hostname, ngx_cycle->hostname.data, ngx_cycle->hostname.len); + modsec_server->server_hostname[ ngx_cycle->hostname.len] = '\0'; modsecStartConfig(); return NGX_OK; } +static void +ngx_http_modsecurity_terminate(ngx_cycle_t *cycle) +{ + if (modsec_server) { + modsecTerminate(); + modsec_server = NULL; + } +} + static ngx_int_t ngx_http_modsecurity_init(ngx_conf_t *cf) @@ -896,9 +931,6 @@ ngx_http_modsecurity_init(ngx_conf_t *cf) modsecFinalizeConfig(); cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); - if (cmcf == NULL) { - return NGX_ERROR; - } h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers); if (h == NULL) { @@ -921,17 +953,12 @@ ngx_http_modsecurity_init(ngx_conf_t *cf) static ngx_int_t ngx_http_modsecurity_init_process(ngx_cycle_t *cycle) { + /* must set log hook here cf->log maybe changed */ modsecSetLogHook(cycle->log, modsecLog); modsecInitProcess(); return NGX_OK; } -static void -ngx_http_modsecurity_exit_process(ngx_cycle_t *cycle) -{ - modsecTerminate(); -} - /* ** [ENTRY POINT] does : this function called by nginx from the request handler @@ -952,18 +979,18 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: handler"); + /* create / retrive request ctx */ if (r->internal) { - /* we have already processed the request headers with previous loc conf */ - - /* TODO: do we need update ctx and process headers again? */ + ctx = ngx_http_get_module_pool_ctx(r, ngx_http_modsecurity); if (ctx) { + /* we have already processed the request headers */ ngx_http_set_ctx(r, ctx, ngx_http_modsecurity); return NGX_DECLINED; } - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: get internel request ctx failed"); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: request pool ctx empty"); } ctx = ngx_http_modsecurity_create_ctx(r); @@ -978,52 +1005,34 @@ ngx_http_modsecurity_handler(ngx_http_request_t *r) return NGX_ERROR; } - ngx_http_modsecurity_load_request(r); - - if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK) { + /* load request to request rec */ + if (ngx_http_modsecurity_load_request(r) != NGX_OK + || ngx_http_modsecurity_load_headers_in(r) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* processing request headers */ - rc = modsecProcessRequestHeaders(ctx->req); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestHeaders %d", rc); + rc = ngx_http_modsecurity_status(r, modsecProcessRequestHeaders(ctx->req)); - if (rc == DECLINED) { - - if (modsecIsRequestBodyAccessEnabled(ctx->req) - && r->method == NGX_HTTP_POST) { - - /* Processing POST request body, should we process PUT? */ - rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler); - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { - return rc; - } - - return NGX_DONE; - } - /* other method */ - rc = modsecProcessRequestBody(ctx->req); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc); - } - - if (rc != DECLINED) { - - /* Nginx and Apache share same response code */ - if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } + if (rc != NGX_DECLINED) { return rc; } - /* - if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK) { + if (r->method == NGX_HTTP_POST + && modsecIsRequestBodyAccessEnabled(ctx->req) ) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + /* read POST request body, should we process PUT? */ + rc = ngx_http_read_client_request_body(r, ngx_http_modsecurity_body_handler); + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + return rc; + } + + return NGX_DONE; } - */ - - return NGX_DECLINED; + + /* other method */ + return ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req)); } @@ -1038,19 +1047,12 @@ ngx_http_modsecurity_body_handler(ngx_http_request_t *r) ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); if (ngx_http_modsecurity_load_request_body(r) != NGX_OK) { - return ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); } - rc = modsecProcessRequestBody(ctx->req); + rc = ngx_http_modsecurity_status(r, modsecProcessRequestBody(ctx->req)); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessRequestBody %d", rc); - - if (rc != DECLINED) { - /* Nginx and Apache share same response code */ - if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; - } + if (rc != NGX_DECLINED) { return ngx_http_finalize_request(r, rc); } @@ -1070,18 +1072,48 @@ static ngx_int_t ngx_http_modsecurity_header_filter(ngx_http_request_t *r) { ngx_http_modsecurity_loc_conf_t *cf; ngx_http_modsecurity_ctx_t *ctx; + const char *location; + ngx_table_elt_t *h; ngx_int_t rc; + cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity); ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); - if (r != r->main || !cf->enable || ctx->complete) { + /* already processed, checking redirect action. */ + if (ctx && ctx->complete + && r->err_status >= NGX_HTTP_MOVED_PERMANENTLY + && r->err_status < 308) { + + /* 3XX load redirect location header so that we can do redirect in phase 3,4 */ + location = apr_table_get(ctx->req->headers_out, "Location"); + + if (location == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + h = ngx_list_push(&r->headers_out.headers); + if (h == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + h->hash = 1; + h->key.data = (u_char *)"Location"; + h->key.len = ngx_strlen("Location"); + h->value.data = (u_char *)location; + h->value.len = ngx_strlen(location); + + return ngx_http_next_header_filter(r); + } + + if (r != r->main || !cf->enable || ctx == NULL ||ctx->complete) { return ngx_http_next_header_filter(r); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: header filter"); - if (r->method == NGX_HTTP_HEAD || r->header_only) { + /* header only or SecResponseBodyAccess off */ + if (r->header_only || (!modsecIsResponseBodyAccessEnabled(ctx->req)) ) { ctx->complete = 1; @@ -1091,26 +1123,26 @@ ngx_http_modsecurity_header_filter(ngx_http_request_t *r) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - rc = modsecProcessResponse(ctx->req); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc); + rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req)); - if (rc == DECLINED || rc == APR_SUCCESS) { - - if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK - || ngx_http_modsecurity_save_headers_out(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - return ngx_http_next_header_filter(r); + if (rc != NGX_DECLINED) { + return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); } - if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK + || ngx_http_modsecurity_save_headers_out(r) != NGX_OK) { + return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); } - return rc; + return ngx_http_next_header_filter(r); } + /* SecResponseBodyAccess on, process rules in body filter */ + + /* pretend we are ngx_http_header_filter */ + r->header_sent = 1; + + r->filter_need_in_memory = 1; return NGX_OK; } @@ -1122,80 +1154,105 @@ ngx_http_modsecurity_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_http_modsecurity_ctx_t *ctx; ngx_int_t rc; apr_off_t content_length; + ngx_chain_t *cl, *out; + ngx_int_t last_buf = 0; cf = ngx_http_get_module_loc_conf(r, ngx_http_modsecurity); ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity); - if (r != r->main || !cf->enable || ctx->complete) { + if (r != r->main || !cf->enable || ctx == NULL || ctx->complete) { return ngx_http_next_body_filter(r, in); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "modSecurity: body filter"); - if (in == NULL) { + for (cl = in; cl; cl = cl->next) { + apr_bucket *e; + ngx_buf_t *buf = cl->buf; + apr_bucket_brigade *bb = ctx->brigade; + off_t size = ngx_buf_size(buf); + if (size) { + char *data = apr_pmemdup(bb->p, buf->pos, size); + if (data == NULL) { + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + e = apr_bucket_pool_create(data , size, bb->p, bb->bucket_alloc); + if (e == NULL) { + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + APR_BRIGADE_INSERT_TAIL(bb, e); + } + + if (buf->last_buf) { + last_buf = 1; + buf->last_buf = 0; + e = apr_bucket_eos_create(bb->bucket_alloc); + if (e == NULL) { + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + APR_BRIGADE_INSERT_TAIL(bb, e); + break; + } + + buf->pos = buf->last; + } + + if (!last_buf) { return NGX_AGAIN; } - rc = move_chain_to_brigade(in, ctx->brigade, r->pool, 0); - if (rc != NGX_OK) { - return rc; - } - /* last buf has been saved */ - ctx->complete = 1; modsecSetResponseBrigade(ctx->req, ctx->brigade); - // TODO: do we need reload headers_in ? - // if (ngx_http_modsecurity_load_headers_in(r) != NGX_OK || ngx_http_modsecurity_load_headers_out(r) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); } - rc = modsecProcessResponse(ctx->req); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ModSecurity: modsecProcessResponse %d", rc); + rc = ngx_http_modsecurity_status(r, modsecProcessResponse(ctx->req)); - if (rc == DECLINED || rc == APR_SUCCESS) { - - in = NULL; - - apr_brigade_length(ctx->brigade, 0, &content_length); - - rc = move_brigade_to_chain(ctx->brigade, &in, r->pool); - if (rc == NGX_ERROR) { - return NGX_ERROR; - } - - if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK - ||ngx_http_modsecurity_save_headers_out(r) != NGX_OK) { - - return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); - } - - if (r->headers_out.content_length_n != -1) { - - r->headers_out.content_length_n = content_length; - r->headers_out.content_length = NULL; /* header filter will set this */ - } - - rc = ngx_http_next_header_filter(r); - - if (rc == NGX_ERROR || rc > NGX_OK) { - return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); - } - - return ngx_http_next_body_filter(r, in); + if (rc != NGX_DECLINED) { + return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); } - if (rc < NGX_HTTP_SPECIAL_RESPONSE || rc >= 600) { - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + apr_brigade_length(ctx->brigade, 0, &content_length); + + rc = move_brigade_to_chain(ctx->brigade, &out, r->pool); + if (rc == NGX_ERROR) { + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); } - return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); + if (ngx_http_modsecurity_save_headers_in(r) != NGX_OK + ||ngx_http_modsecurity_save_headers_out(r) != NGX_OK) { + + return ngx_http_filter_finalize_request(r, + &ngx_http_modsecurity, NGX_HTTP_INTERNAL_SERVER_ERROR); + } + + if (r->headers_out.content_length_n != -1) { + + r->headers_out.content_length_n = content_length; + r->headers_out.content_length = NULL; /* header filter will set this */ + } + + r->header_sent = 0; + rc = ngx_http_next_header_filter(r); + + if (rc == NGX_ERROR || rc > NGX_OK) { + return ngx_http_filter_finalize_request(r, &ngx_http_modsecurity, rc); + } + + return ngx_http_next_body_filter(r, out); } +#define TXID_SIZE 25 static ngx_http_modsecurity_ctx_t * ngx_http_modsecurity_create_ctx(ngx_http_request_t *r) @@ -1205,6 +1262,9 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r) ngx_http_modsecurity_ctx_t *ctx; apr_sockaddr_t *asa; struct sockaddr_in *sin; + char *txid; + unsigned char salt[TXID_SIZE]; + int i; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; #endif @@ -1278,7 +1338,26 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r) ctx->req = modsecNewRequest(ctx->connection, cf->config); apr_table_setn(ctx->req->notes, NOTE_NGINX_REQUEST_CTX, (const char *) ctx); - apr_table_setn(ctx->req->subprocess_env, "UNIQUE_ID", "12345"); + apr_generate_random_bytes(salt, TXID_SIZE); + + txid = apr_pcalloc (ctx->req->pool, TXID_SIZE); + apr_base64_encode (txid, (const char*)salt, TXID_SIZE); + + for(i=0;i= 0x30) && (salt[i] <= 0x39)) {} + else if((salt[i] >= 0x40) && (salt[i] <= 0x5A)) {} + else if((salt[i] >= 0x61) && (salt[i] <= 0x7A)) {} + else { + if((i%2)==0) + salt[i] = 0x41; + else + salt[i] = 0x63; + } + } + + salt[TXID_SIZE-1] = '\0'; + + apr_table_setn(ctx->req->subprocess_env, "UNIQUE_ID", apr_psprintf(ctx->req->pool, "%s", salt)); ctx->brigade = apr_brigade_create(ctx->req->pool, ctx->req->connection->bucket_alloc); @@ -1289,7 +1368,7 @@ ngx_http_modsecurity_create_ctx(ngx_http_request_t *r) return ctx; } -static void + static void ngx_http_modsecurity_cleanup(void *data) { ngx_http_modsecurity_ctx_t *ctx = data; @@ -1299,7 +1378,7 @@ ngx_http_modsecurity_cleanup(void *data) } } -static char * + static char * ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_modsecurity_loc_conf_t *mscf = conf; @@ -1325,7 +1404,7 @@ ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) msg = modsecProcessConfig(mscf->config, (const char *)value[1].data, NULL); if (msg != NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "ModSecurityConfig in %s:%ui: %s", - cf->conf_file->file.name.data, cf->conf_file->line, msg); + cf->conf_file->file.name.data, cf->conf_file->line, msg); return NGX_CONF_ERROR; } @@ -1333,7 +1412,7 @@ ngx_http_modsecurity_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } -static char * + static char * ngx_http_modsecurity_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_modsecurity_loc_conf_t *mscf = conf; @@ -1351,7 +1430,7 @@ ngx_http_modsecurity_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } -static int + static int ngx_http_modsecurity_drop_action(request_rec *r) { ngx_http_modsecurity_ctx_t *ctx; diff --git a/nginx/modsecurity/ngx_pool_context.c b/nginx/modsecurity/ngx_pool_context.c index 13ad3e9a..b1a0607c 100644 --- a/nginx/modsecurity/ngx_pool_context.c +++ b/nginx/modsecurity/ngx_pool_context.c @@ -196,7 +196,7 @@ ngx_pool_context_init_conf(ngx_cycle_t *cycle, void *conf) { ngx_pool_context_conf_t *pcf = conf; - ngx_conf_init_uint_value(pcf->size, NGX_POOL_CTX_SIZE); + ngx_conf_init_uint_value(pcf->size, cycle->connection_n); ngx_pool_context_hash_size = pcf->size; diff --git a/standalone/Debug/CL.read.1.tlog b/standalone/Debug/CL.read.1.tlog new file mode 100644 index 00000000..56b9ce82 Binary files /dev/null and b/standalone/Debug/CL.read.1.tlog differ diff --git a/standalone/Debug/CL.write.1.tlog b/standalone/Debug/CL.write.1.tlog new file mode 100644 index 00000000..836eb92d Binary files /dev/null and b/standalone/Debug/CL.write.1.tlog differ diff --git a/standalone/Debug/acmp.obj b/standalone/Debug/acmp.obj new file mode 100644 index 00000000..273b591d Binary files /dev/null and b/standalone/Debug/acmp.obj differ diff --git a/standalone/Debug/apache2_config.obj b/standalone/Debug/apache2_config.obj new file mode 100644 index 00000000..1080b6b3 Binary files /dev/null and b/standalone/Debug/apache2_config.obj differ diff --git a/standalone/Debug/apache2_io.obj b/standalone/Debug/apache2_io.obj new file mode 100644 index 00000000..23c8d838 Binary files /dev/null and b/standalone/Debug/apache2_io.obj differ diff --git a/standalone/Debug/apache2_util.obj b/standalone/Debug/apache2_util.obj new file mode 100644 index 00000000..c87ef99b Binary files /dev/null and b/standalone/Debug/apache2_util.obj differ diff --git a/standalone/Debug/api.obj b/standalone/Debug/api.obj new file mode 100644 index 00000000..0da766b9 Binary files /dev/null and b/standalone/Debug/api.obj differ diff --git a/standalone/Debug/buckets.obj b/standalone/Debug/buckets.obj new file mode 100644 index 00000000..7ad6f437 Binary files /dev/null and b/standalone/Debug/buckets.obj differ diff --git a/standalone/Debug/cl.command.1.tlog b/standalone/Debug/cl.command.1.tlog new file mode 100644 index 00000000..4b830684 Binary files /dev/null and b/standalone/Debug/cl.command.1.tlog differ diff --git a/standalone/Debug/config.obj b/standalone/Debug/config.obj new file mode 100644 index 00000000..4f9e6d36 Binary files /dev/null and b/standalone/Debug/config.obj differ diff --git a/standalone/Debug/filters.obj b/standalone/Debug/filters.obj new file mode 100644 index 00000000..9d8c9fd5 Binary files /dev/null and b/standalone/Debug/filters.obj differ diff --git a/standalone/Debug/hooks.obj b/standalone/Debug/hooks.obj new file mode 100644 index 00000000..79198b36 Binary files /dev/null and b/standalone/Debug/hooks.obj differ diff --git a/standalone/Debug/link-cvtres.read.1.tlog b/standalone/Debug/link-cvtres.read.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link-cvtres.write.1.tlog b/standalone/Debug/link-cvtres.write.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link-rc.read.1.tlog b/standalone/Debug/link-rc.read.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link-rc.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link-rc.write.1.tlog b/standalone/Debug/link-rc.write.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link-rc.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link.command.1.tlog b/standalone/Debug/link.command.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link.command.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link.read.1.tlog b/standalone/Debug/link.read.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/link.write.1.tlog b/standalone/Debug/link.write.1.tlog new file mode 100644 index 00000000..46b134b1 --- /dev/null +++ b/standalone/Debug/link.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/standalone/Debug/main.obj b/standalone/Debug/main.obj new file mode 100644 index 00000000..bdcb7d6a Binary files /dev/null and b/standalone/Debug/main.obj differ diff --git a/standalone/Debug/mod_security2.obj b/standalone/Debug/mod_security2.obj new file mode 100644 index 00000000..55443f4d Binary files /dev/null and b/standalone/Debug/mod_security2.obj differ diff --git a/standalone/Debug/modsecurity.obj b/standalone/Debug/modsecurity.obj new file mode 100644 index 00000000..25f24c15 Binary files /dev/null and b/standalone/Debug/modsecurity.obj differ diff --git a/standalone/Debug/msc_crypt.obj b/standalone/Debug/msc_crypt.obj new file mode 100644 index 00000000..03cc1cff Binary files /dev/null and b/standalone/Debug/msc_crypt.obj differ diff --git a/standalone/Debug/msc_geo.obj b/standalone/Debug/msc_geo.obj new file mode 100644 index 00000000..9be499f7 Binary files /dev/null and b/standalone/Debug/msc_geo.obj differ diff --git a/standalone/Debug/msc_gsb.obj b/standalone/Debug/msc_gsb.obj new file mode 100644 index 00000000..3a44f0b4 Binary files /dev/null and b/standalone/Debug/msc_gsb.obj differ diff --git a/standalone/Debug/msc_logging.obj b/standalone/Debug/msc_logging.obj new file mode 100644 index 00000000..15b1f7d0 Binary files /dev/null and b/standalone/Debug/msc_logging.obj differ diff --git a/standalone/Debug/msc_lua.obj b/standalone/Debug/msc_lua.obj new file mode 100644 index 00000000..ea14cd9d Binary files /dev/null and b/standalone/Debug/msc_lua.obj differ diff --git a/standalone/Debug/msc_multipart.obj b/standalone/Debug/msc_multipart.obj new file mode 100644 index 00000000..92755abd Binary files /dev/null and b/standalone/Debug/msc_multipart.obj differ diff --git a/standalone/Debug/msc_parsers.obj b/standalone/Debug/msc_parsers.obj new file mode 100644 index 00000000..c9b280ed Binary files /dev/null and b/standalone/Debug/msc_parsers.obj differ diff --git a/standalone/Debug/msc_pcre.obj b/standalone/Debug/msc_pcre.obj new file mode 100644 index 00000000..38faf888 Binary files /dev/null and b/standalone/Debug/msc_pcre.obj differ diff --git a/standalone/Debug/msc_release.obj b/standalone/Debug/msc_release.obj new file mode 100644 index 00000000..1f42c677 Binary files /dev/null and b/standalone/Debug/msc_release.obj differ diff --git a/standalone/Debug/msc_reqbody.obj b/standalone/Debug/msc_reqbody.obj new file mode 100644 index 00000000..bd754e83 Binary files /dev/null and b/standalone/Debug/msc_reqbody.obj differ diff --git a/standalone/Debug/msc_tree.obj b/standalone/Debug/msc_tree.obj new file mode 100644 index 00000000..5756dd03 Binary files /dev/null and b/standalone/Debug/msc_tree.obj differ diff --git a/standalone/Debug/msc_unicode.obj b/standalone/Debug/msc_unicode.obj new file mode 100644 index 00000000..9f634752 Binary files /dev/null and b/standalone/Debug/msc_unicode.obj differ diff --git a/standalone/Debug/msc_util.obj b/standalone/Debug/msc_util.obj new file mode 100644 index 00000000..e8e536a4 Binary files /dev/null and b/standalone/Debug/msc_util.obj differ diff --git a/standalone/Debug/msc_xml.obj b/standalone/Debug/msc_xml.obj new file mode 100644 index 00000000..cdd563df Binary files /dev/null and b/standalone/Debug/msc_xml.obj differ diff --git a/standalone/Debug/persist_dbm.obj b/standalone/Debug/persist_dbm.obj new file mode 100644 index 00000000..39ad803b Binary files /dev/null and b/standalone/Debug/persist_dbm.obj differ diff --git a/standalone/Debug/re.obj b/standalone/Debug/re.obj new file mode 100644 index 00000000..245e35ac Binary files /dev/null and b/standalone/Debug/re.obj differ diff --git a/standalone/Debug/re_actions.obj b/standalone/Debug/re_actions.obj new file mode 100644 index 00000000..f7e68a9e Binary files /dev/null and b/standalone/Debug/re_actions.obj differ diff --git a/standalone/Debug/re_operators.obj b/standalone/Debug/re_operators.obj new file mode 100644 index 00000000..585f773c Binary files /dev/null and b/standalone/Debug/re_operators.obj differ diff --git a/standalone/Debug/re_tfns.obj b/standalone/Debug/re_tfns.obj new file mode 100644 index 00000000..7d74a9f1 Binary files /dev/null and b/standalone/Debug/re_tfns.obj differ diff --git a/standalone/Debug/re_variables.obj b/standalone/Debug/re_variables.obj new file mode 100644 index 00000000..87457577 Binary files /dev/null and b/standalone/Debug/re_variables.obj differ diff --git a/standalone/Debug/regex.obj b/standalone/Debug/regex.obj new file mode 100644 index 00000000..6be34515 Binary files /dev/null and b/standalone/Debug/regex.obj differ diff --git a/standalone/Debug/server.obj b/standalone/Debug/server.obj new file mode 100644 index 00000000..0fdf699a Binary files /dev/null and b/standalone/Debug/server.obj differ diff --git a/standalone/Debug/standalone.Build.CppClean.log b/standalone/Debug/standalone.Build.CppClean.log new file mode 100644 index 00000000..9eae8d5a --- /dev/null +++ b/standalone/Debug/standalone.Build.CppClean.log @@ -0,0 +1,84 @@ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_PCRE.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_RELEASE.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_REQBODY.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_TREE.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_UNICODE.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_UTIL.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_XML.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\PERSIST_DBM.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\RE.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\RE_ACTIONS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\RE_OPERATORS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\RE_TFNS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\RE_VARIABLES.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\API.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\BUCKETS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\CONFIG.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\FILTERS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\HOOKS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\REGEX.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\SERVER.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\ACMP.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\APACHE2_CONFIG.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\APACHE2_IO.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\APACHE2_UTIL.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MODSECURITY.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MOD_SECURITY2.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_CRYPT.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_GEO.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_GSB.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_LOGGING.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_LUA.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_MULTIPART.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MSC_PARSERS.OBJ +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\VC110.PDB +C:\WORK\MOD_SECURITY2\STANDALONE\DEBUG\MAIN.OBJ +c:\work\mod_security2\standalone\Debug\acmp.obj +c:\work\mod_security2\standalone\Debug\apache2_config.obj +c:\work\mod_security2\standalone\Debug\apache2_io.obj +c:\work\mod_security2\standalone\Debug\apache2_util.obj +c:\work\mod_security2\standalone\Debug\api.obj +c:\work\mod_security2\standalone\Debug\buckets.obj +c:\work\mod_security2\standalone\Debug\config.obj +c:\work\mod_security2\standalone\Debug\filters.obj +c:\work\mod_security2\standalone\Debug\hooks.obj +c:\work\mod_security2\standalone\Debug\main.obj +c:\work\mod_security2\standalone\Debug\modsecurity.obj +c:\work\mod_security2\standalone\Debug\mod_security2.obj +c:\work\mod_security2\standalone\Debug\msc_crypt.obj +c:\work\mod_security2\standalone\Debug\msc_geo.obj +c:\work\mod_security2\standalone\Debug\msc_gsb.obj +c:\work\mod_security2\standalone\Debug\msc_logging.obj +c:\work\mod_security2\standalone\Debug\msc_lua.obj +c:\work\mod_security2\standalone\Debug\msc_multipart.obj +c:\work\mod_security2\standalone\Debug\msc_parsers.obj +c:\work\mod_security2\standalone\Debug\msc_pcre.obj +c:\work\mod_security2\standalone\Debug\msc_release.obj +c:\work\mod_security2\standalone\Debug\msc_reqbody.obj +c:\work\mod_security2\standalone\Debug\msc_tree.obj +c:\work\mod_security2\standalone\Debug\msc_unicode.obj +c:\work\mod_security2\standalone\Debug\msc_util.obj +c:\work\mod_security2\standalone\Debug\msc_xml.obj +c:\work\mod_security2\standalone\Debug\persist_dbm.obj +c:\work\mod_security2\standalone\Debug\re.obj +c:\work\mod_security2\standalone\Debug\regex.obj +c:\work\mod_security2\standalone\Debug\re_actions.obj +c:\work\mod_security2\standalone\Debug\re_operators.obj +c:\work\mod_security2\standalone\Debug\re_tfns.obj +c:\work\mod_security2\standalone\Debug\re_variables.obj +c:\work\mod_security2\standalone\Debug\server.obj +c:\work\mod_security2\standalone\Debug\cl.command.1.tlog +c:\work\mod_security2\standalone\Debug\CL.read.1.tlog +c:\work\mod_security2\standalone\Debug\CL.write.1.tlog +c:\work\mod_security2\standalone\Debug\link-cvtres.read.1.tlog +c:\work\mod_security2\standalone\Debug\link-cvtres.write.1.tlog +c:\work\mod_security2\standalone\Debug\link-rc.read.1.tlog +c:\work\mod_security2\standalone\Debug\link-rc.write.1.tlog +c:\work\mod_security2\standalone\Debug\link.command.1.tlog +c:\work\mod_security2\standalone\Debug\link.read.1.tlog +c:\work\mod_security2\standalone\Debug\link.write.1.tlog +c:\work\mod_security2\standalone\Debug\standalone.exp +c:\work\mod_security2\standalone\Debug\vc110.idb +c:\work\mod_security2\standalone\Debug\standalone.pdb +c:\work\mod_security2\standalone\Debug\vc110.pdb +C:\work\mod_security2\standalone\Debug\standalone.pdb diff --git a/standalone/Debug/standalone.exp b/standalone/Debug/standalone.exp new file mode 100644 index 00000000..c4871df5 Binary files /dev/null and b/standalone/Debug/standalone.exp differ diff --git a/standalone/Debug/standalone.lastbuildstate b/standalone/Debug/standalone.lastbuildstate new file mode 100644 index 00000000..9fe15e06 --- /dev/null +++ b/standalone/Debug/standalone.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v110:false +Debug|Win32|C:\work\mod_security2\standalone\| diff --git a/standalone/Debug/standalone.lib b/standalone/Debug/standalone.lib new file mode 100644 index 00000000..dcb76f1f Binary files /dev/null and b/standalone/Debug/standalone.lib differ diff --git a/standalone/Debug/standalone.log b/standalone/Debug/standalone.log new file mode 100644 index 00000000..f34f525d --- /dev/null +++ b/standalone/Debug/standalone.log @@ -0,0 +1,90 @@ +Build started 8/23/2013 12:59:45 PM. + 1>Project "c:\work\mod_security2\standalone\standalone.vcxproj" on node 2 (Build target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\CL.exe /c /I"C:\work\pcre-8.30\include" /I"C:\work\pcre-8.30" /I"C:\work\libxml2-2.7.7\include" /IC:\apache22\include /I..\apache2 /Ic:\work\apache24\include /ZI /nologo /W3 /WX- /Od /Oy- /D _MBCS /D _MBCS /D WIN32 /D WINNT /D inline=APR_INLINE /D AP_DECLARE_STATIC /D VERSION_STANDALONE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc110.pdb" /Gd /TC /wd4244 /wd4018 /analyze- /errorReport:prompt ..\apache2\acmp.c ..\apache2\apache2_config.c ..\apache2\apache2_io.c ..\apache2\apache2_util.c ..\apache2\modsecurity.c ..\apache2\mod_security2.c ..\apache2\msc_crypt.c ..\apache2\msc_geo.c ..\apache2\msc_gsb.c ..\apache2\msc_logging.c ..\apache2\msc_lua.c ..\apache2\msc_multipart.c ..\apache2\msc_parsers.c ..\apache2\msc_pcre.c ..\apache2\msc_release.c ..\apache2\msc_reqbody.c ..\apache2\msc_tree.c ..\apache2\msc_unicode.c ..\apache2\msc_util.c ..\apache2\msc_xml.c ..\apache2\persist_dbm.c ..\apache2\re.c ..\apache2\re_actions.c ..\apache2\re_operators.c ..\apache2\re_tfns.c ..\apache2\re_variables.c api.c buckets.c config.c filters.c hooks.c regex.c server.c + server.c + regex.c + hooks.c + filters.c + config.c + buckets.c + api.c + 1>c:\work\mod_security2\standalone\api.c(226): warning C4101: 'rc' : unreferenced local variable + re_variables.c + re_tfns.c + re_operators.c + re_actions.c + re.c + persist_dbm.c + msc_xml.c + msc_util.c + msc_unicode.c + msc_tree.c + msc_reqbody.c + msc_release.c + msc_pcre.c + Generating Code... + Compiling... + msc_parsers.c + msc_multipart.c + msc_lua.c + msc_logging.c + msc_gsb.c + msc_geo.c + msc_crypt.c + 1>c:\work\mod_security2\apache2\msc_crypt.c(70): warning C4101: 'i' : unreferenced local variable + mod_security2.c + modsecurity.c + apache2_util.c + apache2_io.c + apache2_config.c + acmp.c + Generating Code... + C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\CL.exe /c /I"C:\work\pcre-8.30\include" /I"C:\work\pcre-8.30" /I"C:\work\libxml2-2.7.7\include" /IC:\apache22\include /I..\apache2 /Ic:\work\apache24\include /ZI /nologo /W3 /WX- /Od /Oy- /D _MBCS /D _MBCS /D WIN32 /D WINNT /D inline=APR_INLINE /D AP_DECLARE_STATIC /D VERSION_STANDALONE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc110.pdb" /Gd /TP /wd4244 /wd4018 /analyze- /errorReport:prompt main.cpp + main.cpp + 1>c:\work\mod_security2\standalone\main.cpp(16): warning C4005: 'inline' : macro redefinition + command-line arguments : see previous definition of 'inline' + Link: + C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\work\mod_security2\standalone\Debug\standalone.exe" /INCREMENTAL /NOLOGO /LIBPATH:c:\drop\x86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "libapr-1.lib" "libaprutil-1.lib" pcre.lib libxml2.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\work\mod_security2\standalone\Debug\standalone.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\work\mod_security2\standalone\Debug\standalone.lib" /MACHINE:X86 Debug\acmp.obj + Debug\apache2_config.obj + Debug\apache2_io.obj + Debug\apache2_util.obj + Debug\modsecurity.obj + Debug\mod_security2.obj + Debug\msc_crypt.obj + Debug\msc_geo.obj + Debug\msc_gsb.obj + Debug\msc_logging.obj + Debug\msc_lua.obj + Debug\msc_multipart.obj + Debug\msc_parsers.obj + Debug\msc_pcre.obj + Debug\msc_release.obj + Debug\msc_reqbody.obj + Debug\msc_tree.obj + Debug\msc_unicode.obj + Debug\msc_util.obj + Debug\msc_xml.obj + Debug\persist_dbm.obj + Debug\re.obj + Debug\re_actions.obj + Debug\re_operators.obj + Debug\re_tfns.obj + Debug\re_variables.obj + Debug\api.obj + Debug\buckets.obj + Debug\config.obj + Debug\filters.obj + Debug\hooks.obj + Debug\main.obj + Debug\regex.obj + Debug\server.obj + Creating library C:\work\mod_security2\standalone\Debug\standalone.lib and object C:\work\mod_security2\standalone\Debug\standalone.exp + 1>re_operators.obj : error LNK2019: unresolved external symbol _libinjection_sqli_init referenced in function _msre_op_detectSQLi_execute + 1>re_operators.obj : error LNK2019: unresolved external symbol _libinjection_is_sqli referenced in function _msre_op_detectSQLi_execute + 1>C:\work\mod_security2\standalone\Debug\standalone.exe : fatal error LNK1120: 2 unresolved externals + 1>Done Building Project "c:\work\mod_security2\standalone\standalone.vcxproj" (Build target(s)) -- FAILED. + +Build FAILED. + +Time Elapsed 00:00:15.65 diff --git a/standalone/Debug/standalone.pdb b/standalone/Debug/standalone.pdb new file mode 100644 index 00000000..56cb15db Binary files /dev/null and b/standalone/Debug/standalone.pdb differ diff --git a/standalone/Debug/standalone.unsuccessfulbuild b/standalone/Debug/standalone.unsuccessfulbuild new file mode 100644 index 00000000..e69de29b diff --git a/standalone/Debug/vc110.idb b/standalone/Debug/vc110.idb new file mode 100644 index 00000000..e51b8fec Binary files /dev/null and b/standalone/Debug/vc110.idb differ diff --git a/standalone/Debug/vc110.pdb b/standalone/Debug/vc110.pdb new file mode 100644 index 00000000..023ecaec Binary files /dev/null and b/standalone/Debug/vc110.pdb differ diff --git a/standalone/Makefile.am b/standalone/Makefile.am index 0edfd1f5..dbafc578 100644 --- a/standalone/Makefile.am +++ b/standalone/Makefile.am @@ -13,7 +13,7 @@ standalone_la_SOURCES = ../apache2/mod_security2.c \ ../apache2/msc_util.c ../apache2/msc_pcre.c ../apache2/persist_dbm.c ../apache2/msc_reqbody.c \ ../apache2/msc_geo.c ../apache2/msc_gsb.c ../apache2/msc_unicode.c \ ../apache2/acmp.c ../apache2/msc_lua.c ../apache2/msc_release.c \ - ../apache2/msc_crypt.c ../apache2/msc_tree.c \ + ../apache2/msc_crypt.c ../apache2/msc_tree.c ../apache2/libinjection/libinjection_sqli.c \ api.c buckets.c \ config.c filters.c \ hooks.c \ @@ -72,6 +72,10 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \ @PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@ endif +standalone_INCS = `echo "@LIBXML2_CFLAGS@ @LUA_CFLAGS@" | sed -n 's/ *-I *\([^ ]*\) /\1 /gp'` \ + @APXS_INCLUDEDIR@ @APR_INCLUDEDIR@ @APU_INCLUDEDIR@ +standalone_LIBS = @APR_LINKLD@ @APU_LINKLD@ @APXS_LDFLAGS@ \ + @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@ install-exec-hook: $(pkglib_LTLIBRARIES) @echo "Creating Nginx config file..."; \ rm -f ../nginx/modsecurity/config; \ @@ -79,9 +83,9 @@ install-exec-hook: $(pkglib_LTLIBRARIES) echo "CORE_MODULES=\"\$$CORE_MODULES ngx_pool_context_module\"" >> ../nginx/modsecurity/config; \ echo "HTTP_AUX_FILTER_MODULES=\"ngx_http_modsecurity \$$HTTP_AUX_FILTER_MODULES\"" >> ../nginx/modsecurity/config; \ echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config;\ - echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h\"" >> ../nginx/modsecurity/config; \ - echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm @LUA_LDADD@\"" >> ../nginx/modsecurity/config; \ - echo "CORE_INCS=\"\$$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 /usr/include/libxml2 `echo @LUA_CFLAGS@ | cut -d "I" -f3`\"" >> ../nginx/modsecurity/config; \ + echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config; \ + echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a $(standalone_LIBS) \"" >> ../nginx/modsecurity/config; \ + echo "CORE_INCS=\"\$$CORE_INCS \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 $(standalone_INCS)\"" >> ../nginx/modsecurity/config; \ echo "Removing unused static libraries..."; \ for m in $(pkglib_LTLIBRARIES); do \ base=`echo $$m | sed 's/\..*//'`; \ diff --git a/standalone/Makefile.in b/standalone/Makefile.in index ca84e211..996a0082 100644 --- a/standalone/Makefile.in +++ b/standalone/Makefile.in @@ -1,9 +1,8 @@ -# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile.in generated by automake 1.12.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1994-2012 Free Software Foundation, Inc. + # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -51,7 +50,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = standalone -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/build/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/build/find_apr.m4 \ $(top_srcdir)/build/find_apu.m4 \ @@ -149,13 +149,17 @@ AMTAR = @AMTAR@ APR_CFLAGS = @APR_CFLAGS@ APR_CONFIG = @APR_CONFIG@ APR_CPPFLAGS = @APR_CPPFLAGS@ +APR_INCLUDEDIR = @APR_INCLUDEDIR@ APR_LDADD = @APR_LDADD@ APR_LDFLAGS = @APR_LDFLAGS@ +APR_LINKLD = @APR_LINKLD@ APR_VERSION = @APR_VERSION@ APU_CFLAGS = @APU_CFLAGS@ APU_CONFIG = @APU_CONFIG@ +APU_INCLUDEDIR = @APU_INCLUDEDIR@ APU_LDADD = @APU_LDADD@ APU_LDFLAGS = @APU_LDFLAGS@ +APU_LINKLD = @APU_LINKLD@ APU_VERSION = @APU_VERSION@ APXS = @APXS@ APXS_BINDIR = @APXS_BINDIR@ @@ -381,6 +385,12 @@ standalone_la_LIBADD = @APR_LDADD@ @APU_LDADD@ @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA @SOLARIS_TRUE@ @APR_LDFLAGS@ @APU_LDFLAGS@ @APXS_LDFLAGS@ \ @SOLARIS_TRUE@ @PCRE_LDFLAGS@ @LIBXML2_LDFLAGS@ @LUA_LDFLAGS@ +standalone_INCS = `echo "@LIBXML2_CFLAGS@ @LUA_CFLAGS@" | sed -n 's/ *-I *\([^ ]*\) /\1 /gp'` \ + @APXS_INCLUDEDIR@ @APR_INCLUDEDIR@ @APU_INCLUDEDIR@ + +standalone_LIBS = @APR_LINKLD@ @APU_LINKLD@ @APXS_LDFLAGS@ \ + @PCRE_LDADD@ @LIBXML2_LDADD@ @LUA_LDADD@ + all: all-am .SUFFIXES: @@ -441,12 +451,14 @@ uninstall-pkglibLTLIBRARIES: clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) - @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done + @list='$(pkglib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } standalone.la: $(standalone_la_OBJECTS) $(standalone_la_DEPENDENCIES) $(EXTRA_standalone_la_DEPENDENCIES) $(standalone_la_LINK) -rpath $(pkglibdir) $(standalone_la_OBJECTS) $(standalone_la_LIBADD) $(LIBS) @@ -797,6 +809,20 @@ GTAGS: && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -942,32 +968,30 @@ uninstall-am: uninstall-pkglibLTLIBRARIES .MAKE: install-am install-exec-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-pkglibLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-exec-hook \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am \ - install-pkglibLTLIBRARIES install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-pkglibLTLIBRARIES - + clean-libtool clean-pkglibLTLIBRARIES cscopelist ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkglibLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-pkglibLTLIBRARIES install-exec-hook: $(pkglib_LTLIBRARIES) @echo "Creating Nginx config file..."; \ rm -f ../nginx/modsecurity/config; \ echo "ngx_addon_name=ngx_http_modsecurity" >> ../nginx/modsecurity/config; \ - echo "# HTTP_MODULES=\"\$$HTTP_MODULES ngx_http_modsecurity\"" >> ../nginx/modsecurity/config; \ - echo "HTTP_HEADERS_FILTER_MODULE=\"ngx_http_modsecurity \$$HTTP_HEADERS_FILTER_MODULE\"" >> ../nginx/modsecurity/config; \ - echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c\"" >> ../nginx/modsecurity/config;\ - echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS\"" >> ../nginx/modsecurity/config; \ - echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a -lapr-1 -laprutil-1 -lxml2 -lm @LUA_LDADD@\"" >> ../nginx/modsecurity/config; \ - echo "CORE_INCS=\"\$$CORE_INCS /usr/include/apache2 /usr/include/apr-1.0 /usr/include/httpd /usr/include/apr-1 \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 /usr/include/libxml2 `echo @LUA_CFLAGS@ | cut -d "I" -f3`\"" >> ../nginx/modsecurity/config; \ - echo "have=REQUEST_EARLY . auto/have" >> ../nginx/modsecurity/config;\ + echo "CORE_MODULES=\"\$$CORE_MODULES ngx_pool_context_module\"" >> ../nginx/modsecurity/config; \ + echo "HTTP_AUX_FILTER_MODULES=\"ngx_http_modsecurity \$$HTTP_AUX_FILTER_MODULES\"" >> ../nginx/modsecurity/config; \ + echo "NGX_ADDON_SRCS=\"\$$NGX_ADDON_SRCS \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c\"" >> ../nginx/modsecurity/config;\ + echo "NGX_ADDON_DEPS=\"\$$NGX_ADDON_DEPS \$$ngx_addon_dir/apr_bucket_nginx.h \$$ngx_addon_dir/ngx_pool_context.h \$$ngx_addon_dir/ngx_http_modsecurity.c \$$ngx_addon_dir/apr_bucket_nginx.c \$$ngx_addon_dir/ngx_pool_context.c \"" >> ../nginx/modsecurity/config; \ + echo "CORE_LIBS=\"\$$CORE_LIBS \$$ngx_addon_dir/../../standalone/.libs/standalone.a $(standalone_LIBS) \"" >> ../nginx/modsecurity/config; \ + echo "CORE_INCS=\"\$$CORE_INCS \$$ngx_addon_dir \$$ngx_addon_dir/../../standalone \$$ngx_addon_dir/../../apache2 $(standalone_INCS)\"" >> ../nginx/modsecurity/config; \ echo "Removing unused static libraries..."; \ for m in $(pkglib_LTLIBRARIES); do \ base=`echo $$m | sed 's/\..*//'`; \ diff --git a/standalone/api.c b/standalone/api.c index d656d04a..c7875896 100644 --- a/standalone/api.c +++ b/standalone/api.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -223,40 +223,10 @@ apr_status_t ap_http_in_filter(ap_filter_t *f, apr_bucket_brigade *bb_out, } apr_status_t ap_http_out_filter(ap_filter_t *f, apr_bucket_brigade *b) { - modsec_rec *msr = (modsec_rec *)f->ctx; apr_status_t rc; - apr_bucket_brigade *bb_out; - - bb_out = modsecGetResponseBrigade(f->r); - - - if (bb_out) { - APR_BRIGADE_CONCAT(bb_out, b); - return APR_SUCCESS; - } - - // is there a way to tell whether the response body was modified or not? - // - if((msr->txcfg->content_injection_enabled || msr->content_prepend_len != 0 || msr->content_append_len != 0) - && msr->txcfg->resbody_access) { - - if (modsecWriteResponse != NULL) { - char *data = NULL; - apr_size_t length; - - rc = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp); - - if (rc != APR_SUCCESS) { - msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", rc, - get_apr_error(msr->mp, rc)); - return -1; - } - - /* TODO: return ?*/ - modsecWriteResponse(msr->r, data, msr->stream_output_length); - } - } + apr_bucket_brigade *bb_out = (apr_bucket_brigade *)f->ctx; + APR_BRIGADE_CONCAT(bb_out, b); return APR_SUCCESS; } @@ -551,74 +521,117 @@ int modsecIsResponseBodyAccessEnabled(request_rec *r) } int modsecProcessResponse(request_rec *r) { - int status = DECLINED; + int status; + modsec_rec *msr; + apr_bucket *e; + ap_filter_t *f; + apr_bucket_brigade *bb_in, *bb_out, *bb; - if(r->output_filters != NULL) { - modsec_rec *msr = (modsec_rec *)r->output_filters->ctx; - char buf[8192]; - char *tmp = NULL; - apr_bucket *e = NULL; + if(r->output_filters == NULL) { + return DECLINED; + } + + msr = (modsec_rec *)r->output_filters->ctx; + if (msr == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server, + "ModSecurity: Internal Error: msr is null in output filter."); + ap_remove_output_filter(r->output_filters); + return APR_EGENERAL; + } + + msr->r = r; + + /* create input response brigade */ + bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc); + + if (bb_in == NULL) { + msr_log(msr, 1, "Process response: Failed to create brigade."); + return APR_EGENERAL; + } + + /* get input response brigade */ + bb = modsecGetResponseBrigade(r); + if (bb != NULL) { + APR_BRIGADE_CONCAT(bb_in, bb); + if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb_in))) { + e = apr_bucket_eos_create(bb_in->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb_in, e); + } + } else if (modsecReadResponse != NULL) { unsigned int readcnt = 0; int is_eos = 0; - ap_filter_t *f = NULL; - apr_bucket_brigade *bb_in, *bb = NULL; + char buf[8192]; + while(!is_eos) { + modsecReadResponse(r, buf, 8192, &readcnt, &is_eos); - if (msr == NULL) { - ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server, - "ModSecurity: Internal Error: msr is null in output filter."); - ap_remove_output_filter(r->output_filters); - return send_error_bucket(msr, r->output_filters, HTTP_INTERNAL_SERVER_ERROR); - } - - bb = apr_brigade_create(msr->mp, r->connection->bucket_alloc); - - if (bb == NULL) { - msr_log(msr, 1, "Process response: Failed to create brigade."); - return APR_EGENERAL; - } - - msr->r = r; - - bb_in = modsecGetResponseBrigade(r); - - if (bb_in != NULL) { - APR_BRIGADE_CONCAT(bb, bb_in); - if (!APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) { - e = apr_bucket_eos_create(bb->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); + if(readcnt > 0) { + char *tmp = (char *)apr_palloc(r->pool, readcnt); + memcpy(tmp, buf, readcnt); + e = apr_bucket_pool_create(tmp, readcnt, r->pool, r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb_in, e); } - } else if (modsecReadResponse != NULL) { - while(!is_eos) { - modsecReadResponse(r, buf, 8192, &readcnt, &is_eos); + } - if(readcnt > 0) { - tmp = (char *)apr_palloc(r->pool, readcnt); - memcpy(tmp, buf, readcnt); - e = apr_bucket_pool_create(tmp, readcnt, r->pool, r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } + e = apr_bucket_eos_create(r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb_in, e); + } else { + /* cannot read response body process header only */ + + e = apr_bucket_eos_create(r->connection->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb_in, e); + } + + bb_out = bb ? bb : apr_brigade_create(msr->mp, r->connection->bucket_alloc); + + if (bb_out == NULL) { + msr_log(msr, 1, "Process response: Failed to create brigade."); + return APR_EGENERAL; + } + + /* concat output bucket to bb_out */ + f = ap_add_output_filter("HTTP_OUT", bb_out, r, r->connection); + status = ap_pass_brigade(r->output_filters, bb_in); + ap_remove_output_filter(f); + + if (status == APR_EGENERAL) { + /* retrive response status from bb_out */ + for(e = APR_BRIGADE_FIRST(bb_out); + e != APR_BRIGADE_SENTINEL(bb_out); + e = APR_BUCKET_NEXT(e)) { + if (AP_BUCKET_IS_ERROR(e)) { + return ((ap_bucket_error*) e->data)->status; } - - e = apr_bucket_eos_create(r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } else { - /* cannot read response body process header only */ - - e = apr_bucket_eos_create(r->connection->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, e); - } - - f = ap_add_output_filter("HTTP_OUT", msr, r, r->connection); - status = ap_pass_brigade(r->output_filters, bb); - ap_remove_output_filter(f); - if(status > 0 - && msr->intercept_actionset->intercept_status != 0) { - status = msr->intercept_actionset->intercept_status; } + return APR_EGENERAL; + } + + if (status != DECLINED) { return status; } - return status; + /* copy bb_out */ + // is there a way to tell whether the response body was modified or not? + if (modsecWriteResponse != NULL + && (msr->txcfg->content_injection_enabled || msr->content_prepend_len != 0 || msr->content_append_len != 0) + && msr->txcfg->resbody_access) { + + char *data = NULL; + apr_size_t length; + + status = apr_brigade_pflatten(msr->of_brigade, &data, &length, msr->mp); + + if (status != APR_SUCCESS) { + msr_log(msr, 1, "Output filter: Failed to flatten brigade (%d): %s", status, + get_apr_error(msr->mp, status)); + return APR_EGENERAL; + } + + if ( modsecWriteResponse(msr->r, data, msr->stream_output_length) != APR_SUCCESS) { + return APR_EGENERAL; + } + } + + return DECLINED; } int modsecFinishRequest(request_rec *r) { diff --git a/standalone/api.h b/standalone/api.h index 55f9eef9..4389bc80 100644 --- a/standalone/api.h +++ b/standalone/api.h @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/buckets.c b/standalone/buckets.c index 09e8ffb1..bf8d9d49 100644 --- a/standalone/buckets.c +++ b/standalone/buckets.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/config.c b/standalone/config.c index f26f7ad9..1552c6fa 100644 --- a/standalone/config.c +++ b/standalone/config.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/filters.c b/standalone/filters.c index 4520cba6..c0c15648 100644 --- a/standalone/filters.c +++ b/standalone/filters.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/hooks.c b/standalone/hooks.c index aff3dca6..04c41705 100644 --- a/standalone/hooks.c +++ b/standalone/hooks.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/libapr-1.lib b/standalone/libapr-1.lib new file mode 100644 index 00000000..01b91dd0 Binary files /dev/null and b/standalone/libapr-1.lib differ diff --git a/standalone/libaprutil-1.lib b/standalone/libaprutil-1.lib new file mode 100644 index 00000000..799ec37a Binary files /dev/null and b/standalone/libaprutil-1.lib differ diff --git a/standalone/libxml2.lib b/standalone/libxml2.lib new file mode 100644 index 00000000..485869d1 Binary files /dev/null and b/standalone/libxml2.lib differ diff --git a/standalone/main.cpp b/standalone/main.cpp index 94a5b24d..6f540687 100644 --- a/standalone/main.cpp +++ b/standalone/main.cpp @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/pcre.lib b/standalone/pcre.lib new file mode 100644 index 00000000..17270cee Binary files /dev/null and b/standalone/pcre.lib differ diff --git a/standalone/regex.c b/standalone/regex.c index 3f50e18d..00c6bd10 100644 --- a/standalone/regex.c +++ b/standalone/regex.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/standalone/server.c b/standalone/server.c index 2893d812..53beccf9 100644 --- a/standalone/server.c +++ b/standalone/server.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at @@ -893,7 +893,11 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) #ifndef WIN32 +#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3 unixd_config_rec unixd_config; +#else +unixd_config_rec ap_unixd_config; +#endif const char *ap_server_argv0 = "nginx"; #ifdef HAVE_GETPWNAM @@ -936,13 +940,18 @@ AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp) { apr_finfo_t wrapper; +#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3 unixd_config.user_name = DEFAULT_USER; unixd_config.user_id = ap_uname2id(DEFAULT_USER); unixd_config.group_id = ap_gname2id(DEFAULT_GROUP); - /* unixd_config.chroot_dir = NULL; none */ - - /* Check for suexec */ unixd_config.suexec_enabled = 0; +#else + ap_unixd_config.user_name = DEFAULT_USER; + ap_unixd_config.user_id = ap_uname2id(DEFAULT_USER); + ap_unixd_config.group_id = ap_gname2id(DEFAULT_GROUP); + ap_unixd_config.suexec_enabled = 0; +#endif + /* if ((apr_stat(&wrapper, SUEXEC_BIN, APR_FINFO_NORM, ptemp)) != APR_SUCCESS) { return; @@ -967,6 +976,7 @@ static apr_lockmech_e proc_mutex_mech(apr_proc_mutex_t *pmutex) return APR_LOCK_DEFAULT; } +#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3 AP_DECLARE(apr_status_t) unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) { //////////////// @@ -1038,5 +1048,75 @@ AP_DECLARE(apr_status_t) unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex return unixd_set_proc_mutex_perms(gmutex); #endif /* APR_PROC_MUTEX_IS_GLOBAL */ } +#else +AP_DECLARE(apr_status_t) ap_unixd_set_proc_mutex_perms(apr_proc_mutex_t *pmutex) +{ + if (ap_unixd_config.user_name == NULL) + { + unixd_pre_config(NULL); + } + if (!geteuid()) { + apr_lockmech_e mech = proc_mutex_mech(pmutex); + + switch(mech) { +#if APR_HAS_SYSVSEM_SERIALIZE + case APR_LOCK_SYSVSEM: + { + apr_os_proc_mutex_t ospmutex; +#if !APR_HAVE_UNION_SEMUN + union semun { + long val; + struct semid_ds *buf; + unsigned short *array; + }; +#endif + union semun ick; + struct semid_ds buf; + + apr_os_proc_mutex_get(&ospmutex, pmutex); + buf.sem_perm.uid = ap_unixd_config.user_id; + buf.sem_perm.gid = ap_unixd_config.group_id; + buf.sem_perm.mode = 0600; + ick.buf = &buf; + if (semctl(ospmutex.crossproc, 0, IPC_SET, ick) < 0) { + return errno; + } + } + break; +#endif +#if APR_HAS_FLOCK_SERIALIZE + case APR_LOCK_FLOCK: + { + const char *lockfile = apr_proc_mutex_lockfile(pmutex); + + if (lockfile) { + if (chown(lockfile, ap_unixd_config.user_id, + -1 /* no gid change */) < 0) { + return errno; + } + } + } + break; +#endif + default: + /* do nothing */ + break; + } + } + return APR_SUCCESS; +} + +AP_DECLARE(apr_status_t) ap_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex) +{ +#if !APR_PROC_MUTEX_IS_GLOBAL + apr_os_global_mutex_t osgmutex; + apr_os_global_mutex_get(&osgmutex, gmutex); + return ap_unixd_set_proc_mutex_perms(osgmutex.proc_mutex); +#else /* APR_PROC_MUTEX_IS_GLOBAL */ + /* In this case, apr_proc_mutex_t and apr_global_mutex_t are the same. */ + return ap_unixd_set_proc_mutex_perms(gmutex); +#endif /* APR_PROC_MUTEX_IS_GLOBAL */ +} +#endif #endif diff --git a/standalone/standalone.sdf b/standalone/standalone.sdf new file mode 100644 index 00000000..217db991 Binary files /dev/null and b/standalone/standalone.sdf differ diff --git a/standalone/standalone.v11.suo b/standalone/standalone.v11.suo new file mode 100644 index 00000000..d6ee1f37 Binary files /dev/null and b/standalone/standalone.v11.suo differ diff --git a/standalone/standalone.vcxproj b/standalone/standalone.vcxproj index 5e4bd8ef..8179b0e0 100644 --- a/standalone/standalone.vcxproj +++ b/standalone/standalone.vcxproj @@ -70,7 +70,7 @@ Level3 Disabled - C:\work\pcre-8.30\include;C:\work\pcre-8.30;C:\work\libxml2-2.7.7\include;C:\apache22\include;..\apache2;c:\work\httpd-2.2.24\include + C:\work\pcre-8.30\include;C:\work\pcre-8.30;C:\work\libxml2-2.7.7\include;C:\apache22\include;..\apache2;c:\work\apache24\include _MBCS;%(PreprocessorDefinitions);WIN32;WINNT;inline=APR_INLINE;AP_DECLARE_STATIC;VERSION_STANDALONE 4244;4018 @@ -78,6 +78,7 @@ true kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies);libapr-1.lib;libaprutil-1.lib;pcre.lib;libxml2.lib c:\drop\x86 + Console diff --git a/tests/Makefile.am b/tests/Makefile.am index 2b2b6f46..6790dc4b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -21,7 +21,8 @@ msc_test_SOURCES = msc_test.c \ $(top_srcdir)/apache2/msc_gsb.c \ $(top_srcdir)/apache2/acmp.c \ $(top_srcdir)/apache2/msc_lua.c \ - $(top_srcdir)/apache2/msc_release.c + $(top_srcdir)/apache2/msc_release.c \ + $(top_srcdir)/apache2/libinjection/libinjection_sqli.c msc_test_CFLAGS = @APXS_CFLAGS@ @APR_CFLAGS@ @APU_CFLAGS@ \ @PCRE_CFLAGS@ @LIBXML2_CFLAGS@ @MODSEC_EXTRA_CFLAGS@ @LUA_CFLAGS@ msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \ diff --git a/tests/msc_test.c b/tests/msc_test.c index f6637f50..4085a17e 100644 --- a/tests/msc_test.c +++ b/tests/msc_test.c @@ -1,6 +1,6 @@ /* * ModSecurity for Apache 2.x, http://www.modsecurity.org/ -* Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) +* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License.  You may obtain a copy of the License at diff --git a/tests/op/detectSQLi.t b/tests/op/detectSQLi.t new file mode 100644 index 00000000..8bd9b8c9 --- /dev/null +++ b/tests/op/detectSQLi.t @@ -0,0 +1,18 @@ +{ + type => "op", + name => "detectSQLi", + input => "", + ret => 0 +}, +{ + type => "op", + name => "detectSQLi", + input => "this is not isqli", + ret => 0 +}, +{ + type => "op", + name => "detectSQLi", + input => "ascii(substring(version() from 1 for 1))", + ret => 1 +} diff --git a/tests/op/rx.t b/tests/op/rx.t index 4be49e73..93b48b20 100644 --- a/tests/op/rx.t +++ b/tests/op/rx.t @@ -55,8 +55,8 @@ { type => "op", name => "rx", - param => qr/^([^=])\s*=\s*((?:abc)+(?:def|ghi){2})$/i, - input => "x =AbCDeFgHi", + param => "(?i:(sleep\\((\\s*?)(\\d*?)(\\s*?)\\)|benchmark\\((.*?)\\,(.*?)\\)))", + input => "SELECT pg_sleep(10);", ret => 1, }, diff --git a/tests/regression/nginx/conf/empty.conf b/tests/regression/nginx/conf/empty.conf new file mode 100644 index 00000000..e69de29b diff --git a/tests/regression/nginx/conf/nginx.conf.template b/tests/regression/nginx/conf/nginx.conf.template new file mode 100644 index 00000000..f15ea869 --- /dev/null +++ b/tests/regression/nginx/conf/nginx.conf.template @@ -0,0 +1,22 @@ + +user root; +worker_processes 1; +daemon on; +error_log logs/error.log debug; +events { + worker_connections 1024; +} + +http { + ModSecurityEnabled [% enable %]; + ModSecurityConfig [% config %]; + server { + + listen [% listen %]; + server_name localhost; + location / { + } + } +} + + diff --git a/tests/run-regression-tests-nginx.pl b/tests/run-regression-tests-nginx.pl new file mode 100644 index 00000000..daabad91 --- /dev/null +++ b/tests/run-regression-tests-nginx.pl @@ -0,0 +1,736 @@ +#!/usr/bin/perl +# +# Run regression tests. +# +# Syntax: run-regression-tests.pl [options] [file [N]] +# +# All: run-regression-tests.pl +# All in file: run-regression-tests.pl file +# Nth in file: run-regression-tests.pl file N +# +use strict; +use Time::HiRes qw(gettimeofday sleep); +use POSIX qw(WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG); +use File::Spec qw(rel2abs); +use File::Basename qw(basename dirname); +use File::Path qw(make_path); +use FileHandle; +use IPC::Open2 qw(open2); +use IPC::Open3 qw(open3); +use Getopt::Std; +use Data::Dumper; +use IO::Socket; +use LWP::UserAgent; +use Cwd 'abs_path'; +use Template; +use File::Copy::Recursive qw(dircopy); + +my @TYPES = qw(action config misc rule target); +my $SCRIPT = basename($0); +my $SCRIPT_DIR = File::Spec->rel2abs(dirname($0)); +my $REG_DIR = "$SCRIPT_DIR/regression"; +my $NGINX_DIR = "$REG_DIR/nginx"; +my $NGINX_CONF_TEMP = "$REG_DIR/nginx/conf/nginx.conf.template"; +my $NGINX = q(/usr/local/nginx/sbin/nginx); + +my $PASSED = 0; +my $TOTAL = 0; +my $BUFSIZ = 32768; +my %C = (); +my %FILE = (); +my $UA_NAME = "ModSecurity Regression Tests/1.2.3"; +my $UA = LWP::UserAgent->new; +$UA->agent($UA_NAME); + +$SIG{TERM} = $SIG{INT} = \&handle_interrupt; + +my %opt; +getopts('A:E:D:C:T:H:a:p:dvh', \%opt); + +if ($opt{d}) { + $Data::Dumper::Indent = 1; + $Data::Dumper::Terse = 1; + $Data::Dumper::Pad = ""; + $Data::Dumper::Quotekeys = 0; +} + +sub usage { + print stderr <<"EOT"; +@_ + Usage: $SCRIPT [options] [file [N]] + + Options: + -P path Specify nginx prefix path (default: $NGINX_DIR) + -a file Specify nginx binary (default: $NGINX) + -p port Specify nginx port (default: 8088) + -v Enable verbose output (details on failure). + -d Enable debugging output. + -h This help. +EOT + + exit(1); +} + +usage() if ($opt{h}); + +### Check nginx binary +if (defined $opt{a}) { + $NGINX = $opt{a}; +} +else { + $opt{a} = $NGINX; +} +usage("Invalid Apache startup script: $NGINX\n") unless (-e $NGINX); + + +### Defaults +$opt{P} = "$NGINX_DIR" unless (defined $opt{P}); + +my $CONF_DIR = "$opt{P}/conf"; +my $FILES_DIR = "$opt{P}/logs"; +my $PID_FILE = "$FILES_DIR/nginx.pid"; + +$opt{A} = "$FILES_DIR/modsec_audit.log"; +$opt{D} = "$FILES_DIR/modsec_debug.log"; +$opt{E} = "$FILES_DIR/error.log"; +$opt{C} = "$CONF_DIR/nginx.conf"; +$opt{p} = 8088 unless (defined $opt{p}); +$opt{v} = 1 if ($opt{d}); + +if ( !-d "$opt{P}" ) { + make_path($opt{P}) or die $!; +} + +if ( !-d "$opt{P}/logs" ) { + make_path("$opt{P}/logs") or die $!; +} + +if ( !-d "$opt{P}/html" ) { + make_path("$opt{P}/html") or die $!; +} + +dircopy("$REG_DIR/server_root/htdocs","$opt{P}/html") or die $!; + +%ENV = ( + %ENV, + $NGINX_DIR => $opt{P}, + SERVER_PORT => $opt{p}, + SERVER_NAME => "localhost", +# TEST_NGX_PREFIX => $NGINX_DIR, +# DATA_DIR => $DATA_DIR, +# TEMP_DIR => $TEMP_DIR, +# UPLOAD_DIR => $UPLOAD_DIR, + CONF_DIR => $CONF_DIR, +# MODULES_DIR => $MODULES_DIR, + LOGS_DIR => $FILES_DIR, + SCRIPT_DIR => $SCRIPT_DIR, + REGRESSION_DIR => $REG_DIR, + DIST_ROOT => File::Spec->rel2abs(dirname("$SCRIPT_DIR/../../..")), + AUDIT_LOG => $opt{A}, + DEBUG_LOG => $opt{D}, + ERROR_LOG => $opt{E}, + NGINX_CONF => $opt{C}, +# HTDOCS => $opt{H}, + USER_AGENT => $UA_NAME, + ); + +#dbg("OPTIONS: ", \%opt); + +if (-e "$PID_FILE") { + msg("Shutting down previous instance: $PID_FILE"); + nginx_stop(); +} + +if (defined $ARGV[0]) { + runfile(dirname($ARGV[0]), basename($ARGV[0]), $ARGV[1]); + done(); +} + +for my $type (@TYPES) { + my $dir = "$SCRIPT_DIR/regression/$type"; + my @cfg = (); + +# Get test names + opendir(DIR, "$dir") or quit(1, "Failed to open \"$dir\": $!"); + @cfg = grep { /\.t$/ && -f "$dir/$_" } readdir(DIR); + closedir(DIR); + + for my $cfg (sort @cfg) { + runfile($dir, $cfg); + } +} +done(); + + +sub runfile { + my($dir, $cfg, $testnum) = @_; + my $fn = "$dir/$cfg"; + my @data = (); + my $edata; + my @C = (); + my @test = (); + my $teststr; + my $n = 0; + my $pass = 0; + + open(CFG, "<$fn") or quit(1, "Failed to open \"$fn\": $!"); + @data = ; + + $edata = q/@C = (/ . join("", @data) . q/)/; + eval $edata; + quit(1, "Failed to read test data \"$cfg\": $@") if ($@); + + unless (@C) { + msg("\nNo tests defined for $fn"); + return; + } + + msg("\nLoaded ".@C." tests from $fn"); + for my $t (@C) { + $n++; + next if (defined $testnum and $n != $testnum); + + my $nginx_up = 0; + my %t = %{$t || {}}; + my $id = sprintf("%3d", $n); + my $out = ""; + my $rc = 0; + my $conf_fn; + +# Startup nginx with optionally included conf. + if (exists $t{conf} and defined $t{conf}) { + $conf_fn = sprintf "%s/%s_%s_%06d.conf", + $CONF_DIR, $t{type}, $cfg, $n; +#dbg("Writing test config to: $conf_fn"); + open(CONF, ">$conf_fn") or die "Failed to open conf \"$conf_fn\": $!\n"; + print CONF (ref $t{conf} eq "CODE" ? eval { &{$t{conf}} } : $t{conf}); + msg("$@") if ($@); + close CONF; + my %conf=(config => $conf_fn, enable => "on"); + $nginx_up = nginx_start($t, \%conf) ? 0 : 1; + } + else { + $nginx_up = nginx_start($t) ? 0 : 1; + } + +# Run any prerun setup + if ($rc == 0 and exists $t{prerun} and defined $t{prerun}) { + vrb("Executing perl prerun..."); + $rc = &{$t{prerun}}; + vrb("Perl prerun returned: $rc"); + } + + if ($nginx_up) { +# Perform the request and check response + if (exists $t{request}) { + my $resp = do_request($t{request}); + if (!$resp) { + msg("invalid response"); + vrb("RESPONSE: ", $resp); + $rc = 1; + } + else { + for my $key (keys %{ $t{match_response} || {}}) { + my($neg,$mtype) = ($key =~ m/^(-?)(.*)$/); + my $m = $t{match_response}{$key}; + my $match = match_response($mtype, $resp, $m); + if ($neg and defined $match) { + $rc = 1; + msg("response $mtype matched: $m"); + vrb($resp); + last; + } + elsif (!$neg and !defined $match) { + $rc = 1; + msg("response $mtype failed to match: $m"); + vrb($resp); + last; + } + } + } + } + +# Run any arbitrary perl tests + if ($rc == 0 and exists $t{test} and defined $t{test}) { + dbg("Executing perl test(s)..."); + $rc = eval { &{$t{test}} }; + if (! defined $rc) { + msg("Error running test: $@"); + $rc = -1; + } + dbg("Perl tests returned: $rc"); + } + +# Search for all log matches + if ($rc == 0 and exists $t{match_log} and defined $t{match_log}) { + for my $key (keys %{ $t{match_log} || {}}) { + my($neg,$mtype) = ($key =~ m/^(-?)(.*)$/); + my $m = $t{match_log}{$key}; + my $match = match_log($mtype, @{$m || []}); + if ($neg and defined $match) { + $rc = 1; + msg("$mtype log matched: $m->[0]"); + last; + } + elsif (!$neg and !defined $match) { + $rc = 1; + msg("$mtype log failed to match: $m->[0]"); + last; + } + } + } + +# Search for all file matches + if ($rc == 0 and exists $t{match_file} and defined $t{match_file}) { + sleep 1; # Make sure the file exists + for my $key (keys %{ $t{match_file} || {}}) { + my($neg,$fn) = ($key =~ m/^(-?)(.*)$/); + my $m = $t{match_file}{$key}; + my $match = match_file($fn, $m); + if ($neg and defined $match) { + $rc = 1; + msg("$fn file matched: $m"); + last; + } + elsif (!$neg and !defined $match) { + $rc = 1; + msg("$fn file failed match: $m"); + last; + } + } + } + } + else { + msg("Failed to start nginx."); + $rc = 1; + } + + if ($rc == 0) { + $pass++; + } + else { + vrb("Test Config: $conf_fn"); + vrb("Debug Log: $FILE{debug}{fn}"); + dbg(escape("$FILE{debug}{buf}")); + vrb("Error Log: $FILE{error}{fn}"); + dbg(escape("$FILE{error}{buf}")); + } + + msg(sprintf("%s) %s%s: %s%s", $id, $t{type}, (exists($t{comment}) ? " - $t{comment}" : ""), ($rc ? "failed" : "passed"), ((defined($out) && $out ne "")? " ($out)" : ""))); + + if ($nginx_up) { + $nginx_up = nginx_stop(\%t) ? 0 : 1; + } + + } + + $TOTAL += $testnum ? 1 : $n; + $PASSED += $pass; + + msg(sprintf("Passed: %2d; Failed: %2d", $pass, $testnum ? (1 - $pass) : ($n - $pass))); +} + +# Take out any indenting and translate LF -> CRLF +sub normalize_raw_request_data { + my $r = $_[0]; + +# Allow for indenting in test file + $r =~ s/^[ \t]*\x0d?\x0a//s; + my($indention) = ($r =~ m/^([ \t]*)/s); # indention taken from first line + $r =~ s/^$indention//mg; + $r =~ s/(\x0d?\x0a)[ \t]+$/$1/s; + +# Translate LF to CRLF + $r =~ s/^\x0a/\x0d\x0a/mg; + $r =~ s/([^\x0d])\x0a/$1\x0d\x0a/mg; + + return $r; +} + +sub do_raw_request { + my $sock = new IO::Socket::INET( + Proto => "tcp", + PeerAddr => "localhost", + PeerPort => $opt{p}, + ) or msg("Failed to connect to localhost:$opt{p}: $@"); + return unless ($sock); + +# Join togeather the request + my $r = join("", @_); + dbg($r); + +# Write to socket + print $sock "$r"; + $sock->shutdown(1); + +# Read from socket + my @resp = <$sock>; + $sock->close(); + + return HTTP::Response->parse(join("", @resp)); +} + +sub do_request { + my $r = $_[0]; + +# Allow test to execute code + if (ref $r eq "CODE") { + $r = eval { &$r }; + msg("$@") unless (defined $r); + } + + if (ref $r eq "HTTP::Request") { + my $resp = $UA->request($r); + dbg($resp->request()->as_string()) if ($opt{d}); + return $resp + } + else { + return do_raw_request($r); + } + + return; +} + + +sub match_response { + my($name, $resp, $re) = @_; + + msg("Warning: Empty regular expression.") if (!defined $re or $re eq ""); + + if ($name eq "status") { + return $& if ($resp->code =~ m/$re/); + } + elsif ($name eq "content") { + return $& if ($resp->content =~ m/$re/m); + } + elsif ($name eq "raw") { + return $& if ($resp->as_string =~ m/$re/m); + } + + return; +} + +sub read_log { + my($name, $timeout, $graph) = @_; + return match_log($name, undef, $timeout, $graph); +} + +sub match_log { + my($name, $re, $timeout, $graph) = @_; + my $t0 = gettimeofday; + my($fh,$rbuf) = ($FILE{$name}{fd}, \$FILE{$name}{buf}); + my $n = length($$rbuf); + my $rc = undef; + + unless (defined $fh) { + msg("Error: File \"$name\" is not opened for matching."); + return; + } + + $timeout = 0 unless (defined $timeout); + + my $i = 0; + my $graphed = 0; +READ: { + do { + my $nbytes = $fh->sysread($$rbuf, $BUFSIZ, $n); + if (!defined($nbytes)) { + msg("Error: Could not read \"$name\" log: $!"); + last; + } + elsif (!defined($re) and $nbytes == 0) { + last; + } + +# Remove APR pool debugging + $$rbuf =~ s/POOL DEBUG:[^\n]+PALLOC[^\n]+\n//sg; + + $n = length($$rbuf); + +#dbg("Match \"$re\" in $name \"$$rbuf\" ($n)"); + if ($$rbuf =~ m/$re/m) { + $rc = $&; + last; + } +# TODO: Use select()/poll() + sleep 0.1 unless ($nbytes == $BUFSIZ); + if ($graph and $opt{d}) { + $i++; + if ($i == 10) { + $graphed++; + $i=0; + print STDERR $graph if ($graphed == 1); + print STDERR "." + } + } + } while (gettimeofday - $t0 < $timeout); + } + print STDERR "\n" if ($graphed); + + return $rc; +} + +sub match_file { + my($neg,$fn) = ($_[0] =~ m/^(-?)(.*)$/); + unless (exists $FILE{$fn}) { + eval { + $FILE{$fn}{fn} = $fn; + $FILE{$fn}{fd} = new FileHandle($fn, O_RDONLY) or die "$!\n"; + $FILE{$fn}{fd}->blocking(0); + $FILE{$fn}{buf} = ""; + }; + if ($@) { + msg("Warning: Failed to open file \"$fn\": $@"); + return; + } + } + return match_log($_[0], $_[1]); # timeout makes no sense +} + +sub quote_shell { + my($s) = @_; + return $s unless ($s =~ m|[^\w!%+,\-./:@^]|); + $s =~ s/(['\\])/\\$1/g; + return "'$s'"; +} + +sub escape { + my @new = (); + for my $c (split(//, $_[0])) { + my $oc = ord($c); + push @new, ((($oc >= 0x20 and $oc <= 0x7e) or $oc == 0x0a or $oc == 0x0d) ? $c : sprintf("\\x%02x", ord($c))); +} +join('', @new); +} + +sub dbg { + return unless(@_ and $opt{d}); + my $out = join "", map { + (ref $_ ne "" ? Dumper($_) : $_) + } @_; + $out =~ s/^/DBG: /mg; + print STDOUT "$out\n"; +} + +sub vrb { + return unless(@_ and $opt{v}); + msg(@_); +} + +sub msg { + return unless(@_); + my $out = join "", map { + (ref $_ ne "" ? Dumper($_) : $_) + } @_; + print STDOUT "$out\n"; +} + +sub handle_interrupt { + $SIG{TERM} = $SIG{INT} = \&handle_interrupt; + + msg("Interrupted via SIG$_[0]. Shutting down tests..."); + nginx_stop(); + + quit(1); +} + +sub quit { + my($ec,$msg) = @_; + $ec = 0 unless (defined $_[0]); + + msg("$msg") if (defined $msg); + + exit $ec; +} + +sub done { + if ($PASSED != $TOTAL) { + quit(1, "\n$PASSED/$TOTAL tests passed."); + } + + quit(0, "\nAll tests passed ($TOTAL)."); +} + +sub nginx_stop { + my $t = shift; + my @p = ( + $NGINX, + -p => $opt{P}, + -s => "quit", + ); + + my $nginx_out; + my $nginx_pid = open3(undef, $nginx_out, undef, @p) or quit(1); + my $out = join("\\n", grep(!/POOL DEBUG/, (<$nginx_out>))); + close $nginx_out; + waitpid($nginx_pid, 0); + + my $rc = $?; + if ( WIFEXITED($rc) ) { + $rc = WEXITSTATUS($rc); + vrb("Nginx stop returned with $rc.") if ($rc); + } + elsif( WIFSIGNALED($rc) ) { + msg("Nginx stop failed with signal " . WTERMSIG($rc) . "."); + $rc = -1; + } + else { + msg("Nginx stop failed with unknown error."); + $rc = -1; + } + + sleep 0.5; + if (-e $PID_FILE) { + msg("Nginx stop failed: $PID_FILE still exists"); + } + + return $rc; +} + + +sub nginx_reset_fd { + my($t) = @_; + +# Cleanup + for my $key (keys %FILE) { + if (exists $FILE{$key}{fd} and defined $FILE{$key}{fd}) { + $FILE{$key}{fd}->close(); + } + delete $FILE{$key}; + } + +# Error + eval { + $FILE{error}{fn} = $opt{E}; + $FILE{error}{fd} = new FileHandle($opt{E}, O_RDWR|O_CREAT) or die "$!\n"; + $FILE{error}{fd}->blocking(0); + $FILE{error}{fd}->sysseek(0, 2); + $FILE{error}{buf} = ""; + }; + if ($@) { + msg("Warning: Failed to open file \"$opt{E}\": $@"); + return undef; + } + +# Audit + eval { + $FILE{audit}{fn} = $opt{A}; + $FILE{audit}{fd} = new FileHandle($opt{A}, O_RDWR|O_CREAT) or die "$!\n"; + $FILE{audit}{fd}->blocking(0); + $FILE{audit}{fd}->sysseek(0, 2); + $FILE{audit}{buf} = ""; + }; + if ($@) { + msg("Warning: Failed to open file \"$opt{A}\": $@"); + return undef; + } + +# Debug + eval { + $FILE{debug}{fn} = $opt{D}; + $FILE{debug}{fd} = new FileHandle($opt{D}, O_RDWR|O_CREAT) or die "$!\n"; + $FILE{debug}{fd}->blocking(0); + $FILE{debug}{fd}->sysseek(0, 2); + $FILE{debug}{buf} = ""; + }; + if ($@) { + msg("Warning: Failed to open file \"$opt{D}\": $@"); + return undef; + } + +# Any extras listed in "match_log" + if ($t and exists $t->{match_log}) { + for my $k (keys %{ $t->{match_log} || {} }) { + my($neg,$fn) = ($k =~ m/^(-?)(.*)$/); + next if (!$fn or exists $FILE{$fn}); + eval { + $FILE{$fn}{fn} = $fn; + $FILE{$fn}{fd} = new FileHandle($fn, O_RDWR|O_CREAT) or die "$!\n"; + $FILE{$fn}{fd}->blocking(0); + $FILE{$fn}{fd}->sysseek(0, 2); + $FILE{$fn}{buf} = ""; + }; + if ($@) { + msg("Warning: Failed to open file \"$fn\": $@"); + return undef; + } + } + } +} + +sub encode_chunked { + my($data, $size) = @_; + $size = 128 unless ($size); + my $chunked = ""; + + my $n = 0; + my $bytes = length($data); + while ($bytes >= $size) { + $chunked .= sprintf "%x\x0d\x0a%s\x0d\x0a", $size, substr($data, $n, $size); + $n += $size; + $bytes -= $size; + } + if ($bytes) { + $chunked .= sprintf "%x\x0d\x0a%s\x0d\x0a", $bytes, substr($data, $n, $bytes); + } + $chunked .= "0\x0d\x0a\x0d\x0a" +} + +sub nginx_start { + my ($t) = shift; + my($C) = shift; + + my %conf = ( + listen => "$opt{p}", + config => "$REG_DIR/nginx/conf/empty.conf", + enable => "off", + ); + + while(my($k,$v)= each %$C){ + $conf{$k}=$v; + } + + my ($tt) = Template->new(INCLUDE_PATH => "$REG_DIR/nginx/conf/"); + my ($output); + $tt->process("nginx.conf.template", \%conf, \$output) || die $tt->error; + + open (OUTFILE, ">$opt{C}"); + print OUTFILE "$output"; + close(OUTFILE); + + nginx_reset_fd($t); + + my @p = ($NGINX, -p => $opt{P}); + + my $nginx_out; + my $nginx_pid = open3(undef, $nginx_out, undef, @p) or quit(1); + my $out = join("\\n", grep(!/POOL DEBUG/, (<$nginx_out>))); + close $nginx_out; + waitpid($nginx_pid, 0); + + my $rc = $?; + if ( WIFEXITED($rc) ) { + $rc = WEXITSTATUS($rc); + vrb("Nginx start returned with $rc.") if ($rc); + } + elsif( WIFSIGNALED($rc) ) { + msg("Nginx start failed with signal " . WTERMSIG($rc) . "."); + $rc = -1; + } + else { + msg("Nginx start failed with unknown error."); + $rc = -1; + } + +# Look for startup msg +# unless (defined match_log("error", qr/start worker process/, 60, "Waiting on nginx to start: ")) { +# vrb(join(" ", map { quote_shell($_) } @p)); +# vrb(match_log("error", qr/(^.*ModSecurity: .*)/sm, 10)); +# msg("Nginx server failed to start."); +# nginx_stop(); +# return -1; +# } + + return $rc; +} +