From 6460ec48fb847c46b5aafdabc3c46c141b93a2e5 Mon Sep 17 00:00:00 2001 From: wargio Date: Sat, 5 Mar 2022 14:26:34 +0100 Subject: [PATCH] libnaxsi + unit tests + CI + nginx module --- .clang-format | 26 + .github/workflows/ci.yaml | 38 + .github/workflows/linter.yaml | 32 + .gitignore | 3 + .reuse/dep5 | 24 + .travis.yml | 42 - LICENSE => LICENSES/GPL-3.0-only.txt | 0 LICENSES/LGPL-3.0-only.txt | 71 + build-nginx.sh | 32 + clang-format.py | 121 + libnaxsi/include/naxsi.h | 21 + libnaxsi/include/naxsi_const.h | 49 + libnaxsi/include/naxsi_types.h | 61 + libnaxsi/meson.build | 89 + libnaxsi/meson_options.txt | 2 + libnaxsi/src/naxsi.c | 4 + libnaxsi/src/naxsi_config.c | 48 + libnaxsi/src/naxsi_config.h | 16 + libnaxsi/src/naxsi_list.c | 75 + libnaxsi/src/naxsi_list.h | 31 + libnaxsi/src/naxsi_mem.c | 90 + libnaxsi/src/naxsi_mem.h | 20 + libnaxsi/src/naxsi_rule.c | 49 + libnaxsi/src/naxsi_rule.h | 76 + libnaxsi/src/naxsi_utils.c | 157 + libnaxsi/src/naxsi_utils.h | 13 + libnaxsi/src/naxsi_vector.h | 179 + libnaxsi/subprojects/libinjection.wrap | 4 + .../packagefiles/libinjection/meson.build | 27 + .../packagefiles/pcre2/meson.build | 93 + libnaxsi/subprojects/pcre2.wrap | 4 + libnaxsi/test/minunit.h | 293 + libnaxsi/test/minunit_mem.h | 25 + libnaxsi/test/test_list.c | 100 + libnaxsi/test/test_mem.c | 110 + libnaxsi/test/test_utils.c | 107 + naxsi_nginx_module/config | 18 + naxsi_nginx_module/ngx_http_naxsi_module.c | 214 + naxsi_src/ext/libinjection/example1.c | 30 - naxsi_src/ext/libinjection/fptool.c | 79 - naxsi_src/ext/libinjection/html5_cli.c | 168 - naxsi_src/ext/libinjection/libinjection.h | 65 - .../ext/libinjection/libinjection_html5.c | 847 -- .../ext/libinjection/libinjection_html5.h | 54 - .../ext/libinjection/libinjection_sqli.c | 2298 ---- .../ext/libinjection/libinjection_sqli.h | 295 - .../ext/libinjection/libinjection_sqli_data.h | 9349 ----------------- naxsi_src/ext/libinjection/libinjection_xss.c | 531 - naxsi_src/ext/libinjection/libinjection_xss.h | 21 - naxsi_src/ext/libinjection/reader.c | 314 - naxsi_src/ext/libinjection/sqli_cli.c | 144 - naxsi_src/ext/libinjection/test_speed_sqli.c | 68 - naxsi_src/ext/libinjection/test_speed_xss.c | 84 - naxsi_src/ext/libinjection/testdriver.c | 312 - 54 files changed, 2322 insertions(+), 14701 deletions(-) create mode 100644 .clang-format create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/linter.yaml create mode 100644 .gitignore create mode 100644 .reuse/dep5 delete mode 100644 .travis.yml rename LICENSE => LICENSES/GPL-3.0-only.txt (100%) create mode 100644 LICENSES/LGPL-3.0-only.txt create mode 100644 build-nginx.sh create mode 100755 clang-format.py create mode 100644 libnaxsi/include/naxsi.h create mode 100644 libnaxsi/include/naxsi_const.h create mode 100644 libnaxsi/include/naxsi_types.h create mode 100644 libnaxsi/meson.build create mode 100644 libnaxsi/meson_options.txt create mode 100644 libnaxsi/src/naxsi.c create mode 100644 libnaxsi/src/naxsi_config.c create mode 100644 libnaxsi/src/naxsi_config.h create mode 100644 libnaxsi/src/naxsi_list.c create mode 100644 libnaxsi/src/naxsi_list.h create mode 100644 libnaxsi/src/naxsi_mem.c create mode 100644 libnaxsi/src/naxsi_mem.h create mode 100644 libnaxsi/src/naxsi_rule.c create mode 100644 libnaxsi/src/naxsi_rule.h create mode 100644 libnaxsi/src/naxsi_utils.c create mode 100644 libnaxsi/src/naxsi_utils.h create mode 100644 libnaxsi/src/naxsi_vector.h create mode 100644 libnaxsi/subprojects/libinjection.wrap create mode 100644 libnaxsi/subprojects/packagefiles/libinjection/meson.build create mode 100644 libnaxsi/subprojects/packagefiles/pcre2/meson.build create mode 100644 libnaxsi/subprojects/pcre2.wrap create mode 100644 libnaxsi/test/minunit.h create mode 100644 libnaxsi/test/minunit_mem.h create mode 100644 libnaxsi/test/test_list.c create mode 100644 libnaxsi/test/test_mem.c create mode 100644 libnaxsi/test/test_utils.c create mode 100644 naxsi_nginx_module/config create mode 100644 naxsi_nginx_module/ngx_http_naxsi_module.c delete mode 100644 naxsi_src/ext/libinjection/example1.c delete mode 100644 naxsi_src/ext/libinjection/fptool.c delete mode 100644 naxsi_src/ext/libinjection/html5_cli.c delete mode 100644 naxsi_src/ext/libinjection/libinjection.h delete mode 100644 naxsi_src/ext/libinjection/libinjection_html5.c delete mode 100644 naxsi_src/ext/libinjection/libinjection_html5.h delete mode 100644 naxsi_src/ext/libinjection/libinjection_sqli.c delete mode 100644 naxsi_src/ext/libinjection/libinjection_sqli.h delete mode 100644 naxsi_src/ext/libinjection/libinjection_sqli_data.h delete mode 100644 naxsi_src/ext/libinjection/libinjection_xss.c delete mode 100644 naxsi_src/ext/libinjection/libinjection_xss.h delete mode 100644 naxsi_src/ext/libinjection/reader.c delete mode 100644 naxsi_src/ext/libinjection/sqli_cli.c delete mode 100644 naxsi_src/ext/libinjection/test_speed_sqli.c delete mode 100644 naxsi_src/ext/libinjection/test_speed_xss.c delete mode 100644 naxsi_src/ext/libinjection/testdriver.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..be5902a --- /dev/null +++ b/.clang-format @@ -0,0 +1,26 @@ +Language: Cpp +MaxEmptyLinesToKeep: 1 +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInContainerLiterals: true +BasedOnStyle: LLVM +ContinuationIndentWidth: 8 +IndentCaseLabels: false +IndentFunctionDeclarationAfterType: false +IndentWidth: 8 +UseTab: ForContinuationAndIndentation +ColumnLimit: 0 +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +AllowShortIfStatementsOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortLoopsOnASingleLine: false +AlignAfterOpenBracket: DontAlign +AlignEscapedNewlines: DontAlign +AlignConsecutiveMacros: true +AlignTrailingComments: false +AlignOperands: false +Cpp11BracedListStyle: false +ForEachMacros: ['naxsi_list_foreach'] +SortIncludes: false diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..7564269 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,38 @@ +name: "CI Unit Tests" + +on: + push: + branches: + - main + pull_request: + +jobs: + Normal: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install meson and ninja + run: pip3 install --user meson ninja + - name: Run Unit Tests + run: | + export PATH=${HOME}/Library/Python/3.8/bin:${HOME}/Library/Python/3.9/bin:${HOME}/.local/bin:${PATH} + cd libnaxsi + meson -Dbuildtype=release build + ninja -C build test + + Asan: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install meson and ninja + run: pip3 install --user meson ninja + - name: Run Unit Tests with ASAN + env: + ASAN_OPTIONS: detect_leaks=0,detect_odr_violation=0,allocator_may_return_null=1 + run: | + export PATH=${HOME}/Library/Python/3.8/bin:${HOME}/Library/Python/3.9/bin:${HOME}/.local/bin:${PATH} + cd libnaxsi + meson -Dbuildtype=debugoptimized -Db_sanitize=address,undefined build + ninja -C build test diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml new file mode 100644 index 0000000..cf4c94c --- /dev/null +++ b/.github/workflows/linter.yaml @@ -0,0 +1,32 @@ +name: "Licenses reuse & code lint" + +on: + push: + branches: + - main + pull_request: + +jobs: + licenses: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: REUSE Compliance Check + uses: fsfe/reuse-action@v1.1 + + code: + runs-on: ubuntu-20.04 + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Install wget, software-properties-common, lsb-release (dependencies of LLVM install script) + run: sudo apt --assume-yes install wget software-properties-common lsb-release + - name: Install automatic LLVM 13 + run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 13 + - name: Install clang-format-13 + run: sudo apt --assume-yes install clang-format-13 + - name: Install gitpython + run: sudo pip install gitpython + - name: Run Unit Tests + run: python clang-format.py --verbose --check diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c57505a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +libnaxsi/build*/ +libnaxsi/subprojects/libinjection +libnaxsi/subprojects/pcre2 \ No newline at end of file diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000..991a6d7 --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,24 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Re:WAF +Upstream-Contact: deroad +Source: https://github.com/wargio/rewaf + +Files: *.md *.sh *.py *.yaml .gitignore .clang-format +Copyright: 2022 deroad +License: LGPL-3.0-only + +Files: **/meson.build **/*.wrap **/meson_options.txt +Copyright: 2022 deroad +License: LGPL-3.0-only + +Files: naxsi_nginx_module/config +Copyright: 2022 deroad +License: LGPL-3.0-only + +Files: naxsi_config/** naxsi_src/** nxapi/** t/** .gitattributes +Copyright: 2016, Thibault 'bui' Koechlin +License: GPL-3.0-only + +Files: logo.png +Copyright: 2016-2020, NBS System +License: GPL-3.0-only diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7514930..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -dist: xenial -language: C - -os: - - linux - -cache: - - apt - - pip - -env: - global: - - VER_NGINX=1.9.11 - - COV=0 - -compiler: - - clang - - gcc - -addons: - apt: - packages: - - lcov - - cpanminus - -install: - - gem install coveralls-lcov - - cd ./naxsi_src - - if [ "$CC" == "clang" ]; then COV=0; fi - - make - - sudo cpanm -v --notest Test::Nginx - -before_script: - - lcov --directory "../nginx-${VER_NGINX}" --zerocounters - -script: make test - -after_failure: - - cat ../t/servroot/logs/error.log - - cat /tmp/ngx_error.log - - cat /tmp/ngx_access.log - diff --git a/LICENSE b/LICENSES/GPL-3.0-only.txt similarity index 100% rename from LICENSE rename to LICENSES/GPL-3.0-only.txt diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt new file mode 100644 index 0000000..c9287dd --- /dev/null +++ b/LICENSES/LGPL-3.0-only.txt @@ -0,0 +1,71 @@ +GNU LESSER GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + +As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. + +"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. + +An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. + +A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". + +The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. + +The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. +You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. +If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: + + a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. +The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license document. + +4. Combined Works. +You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license document. + + c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. + + e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) + +5. Combined Libraries. +You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. +The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. diff --git a/build-nginx.sh b/build-nginx.sh new file mode 100644 index 0000000..196c1b2 --- /dev/null +++ b/build-nginx.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e + +if [ ! -d "$1" ]; then + echo "$0 [optional: debug|asan]" + exit 1 +fi + +NGINX_SRC=$(realpath "$1") +OPTION="$2" + +MESON_OPTIONS="--buildtype=release" +if [ "$OPTION" == "debug" ]; then + MESON_OPTIONS="--buildtype=debugoptimized" +elif [ "$OPTION" == "asan" ]; then + MESON_OPTIONS="--buildtype=debugoptimized -Db_sanitize=address,undefined" +fi + +ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# build librewaf +cd "$ROOT_DIR/libnaxsi" +if [ -d "build" ]; then + rm -rf build +fi +meson -Ddefault_library=static $MESON_OPTIONS build +ninja -C build + +# build nginx module +cd "$NGINX_SRC" +./configure --add-dynamic-module="$ROOT_DIR/naxsi_nginx_module/" +make modules diff --git a/clang-format.py b/clang-format.py new file mode 100755 index 0000000..2cca958 --- /dev/null +++ b/clang-format.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: 2021 Anton Kochkov +# SPDX-License-Identifier: LGPL-3.0-only + +import argparse +import glob +import itertools +import subprocess +import sys + +from git import Repo + +dirlist = [ + "libnaxsi", + "naxsi_nginx_module", +] + +skiplist = [ + "subprojects/", + "/build" +] + +patterns = ["*.c", "*.h"] + + +def should_scan(filename): + return any(directory in filename for directory in dirlist) and any( + pattern[1:] in filename for pattern in patterns + ) + + +def skip(filename): + return any(skipfile in filename for skipfile in skiplist) + + +def get_matching_files(): + for directory, pattern in itertools.product(dirlist, patterns): + for filename in glob.iglob(directory + "/**/" + pattern, recursive=True): + if not skip(filename): + yield filename + + +def get_edited_files(args): + repo = Repo() + + for diff in repo.index.diff(args.diff): + filename = diff.a_path + if should_scan(filename) and not skip(filename): + yield filename + + +def build_command(check, verbose, filenames): + cmd = [] + if check: + cmd += ["clang-format", "--style=file", "--Werror", "--dry-run"] + else: + cmd += ["clang-format", "--style=file", "-i"] + if verbose: + cmd += ['--verbose'] + return cmd + filenames + + +def format_files(args, files): + if len(files) == 0: + print("No C files to format.") + sys.exit(0) + cmd = build_command(args.check, args.verbose, files) + r = subprocess.run(cmd, check=False) + sys.exit(r.returncode) + + +def get_file(args): + filename = args.file + if should_scan(filename) and not skip(filename): + return [filename] + + return [] + + +def get_files(args): + if args.diff: + return get_edited_files(args) + + if args.file: + return get_file(args) + + return get_matching_files() + + +def process(args): + files = get_files(args) + format_files(args, list(files)) + + +def parse(): + parser = argparse.ArgumentParser(description="Clang format the rizin project") + parser.add_argument( + "-c", "--check", action="store_true", help="enable the check mode" + ) + parser.add_argument( + "-v", "--verbose", action="store_true", help="use verbose output" + ) + parser.add_argument("-f", "--file", help="formats (or checks) only the given file") + parser.add_argument( + "-d", + "--diff", + type=str, + default=None, + help="format all modified file related to branch", + ) + return parser.parse_args() + + +def main(): + args = parse() + process(args) + + +if __name__ == "__main__": + main() diff --git a/libnaxsi/include/naxsi.h b/libnaxsi/include/naxsi.h new file mode 100644 index 0000000..f0bdd20 --- /dev/null +++ b/libnaxsi/include/naxsi.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_H +#define NAXSI_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +NAXSI_API naxsi_config_t *naxsi_config_new(const naxsi_mem_t *memory, bool defaults_rules); +NAXSI_API void naxsi_config_free(const naxsi_mem_t *memory, naxsi_config_t *nctx); + +#ifdef __cplusplus +} +#endif + +#endif /* NAXSI_H */ diff --git a/libnaxsi/include/naxsi_const.h b/libnaxsi/include/naxsi_const.h new file mode 100644 index 0000000..6dc2963 --- /dev/null +++ b/libnaxsi/include/naxsi_const.h @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_CONST_H +#define NAXSI_CONST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NAXSI_VERSION "1.4.0" +#define NAXSI_VERSION_MAJOR (1) +#define NAXSI_VERSION_MINOR (4) +#define NAXSI_VERSION_NUMBER (0) +#define NAXSI_VERSION_PATCH ((1000000 * NAXSI_VERSION_MAJOR) + (1000 * NAXSI_VERSION_MINOR) + NAXSI_VERSION_PATCH) + +#define NAXSI_KEYWORD_DENIED_URL "DeniedUrl" +#define NAXSI_KEYWORD_IGNORE_IP "IgnoreIP" +#define NAXSI_KEYWORD_IGNORE_CIDR "IgnoreCIDR" +#define NAXSI_KEYWORD_LEARNING_FLAG "LearningMode" +#define NAXSI_KEYWORD_ENABLED_FLAG "SecRulesEnabled" +#define NAXSI_KEYWORD_DISABLED_FLAG "SecRulesDisabled" +#define NAXSI_KEYWORD_CHECK_RULE "CheckRule" +#define NAXSI_KEYWORD_BASIC_RULE "BasicRule" +#define NAXSI_KEYWORD_MAIN_RULE "MainRule" +#define NAXSI_KEYWORD_LIBINJECTION_SQL "LibInjectionSql" +#define NAXSI_KEYWORD_LIBINJECTION_XSS "LibInjectionXss" + +#define NAXSI_MAIN_RULE_ID_WEIRD_REQUEST (1) +#define NAXSI_MAIN_RULE_ID_TOO_BIG_REQUEST (2) +#define NAXSI_MAIN_RULE_ID_INVALID_HEX (10) +#define NAXSI_MAIN_RULE_ID_UNKNOWN_CONTENT_TYPE (11) +#define NAXSI_MAIN_RULE_ID_INVALID_FORMATTED_URL (11) +#define NAXSI_MAIN_RULE_ID_INVALID_POST_FORMAT (13) +#define NAXSI_MAIN_RULE_ID_INVALID_POST_BOUNDARY (14) +#define NAXSI_MAIN_RULE_ID_INVALID_JSON (15) +#define NAXSI_MAIN_RULE_ID_EMPTY_POST (16) +#define NAXSI_MAIN_RULE_ID_LIBINJECTION_SQL (17) +#define NAXSI_MAIN_RULE_ID_LIBINJECTION_XSS (18) +#define NAXSI_MAIN_RULE_ID_NO_GENERIC_RULES (19) +#define NAXSI_MAIN_RULE_ID_BAD_UTF8 (20) + +#ifdef __cplusplus +} +#endif + +#endif /* NAXSI_CONST_H */ diff --git a/libnaxsi/include/naxsi_types.h b/libnaxsi/include/naxsi_types.h new file mode 100644 index 0000000..dba80a8 --- /dev/null +++ b/libnaxsi/include/naxsi_types.h @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_TYPES_H +#define NAXSI_TYPES_H +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef struct naxsi_str { + char *data; + size_t length; +} naxsi_str_t; + +#define naxsi_string(x) \ + { x, strlen(x) } + +typedef void (*naxsi_mem_free_t)(void *user, void *pointer); +typedef void *(*naxsi_mem_malloc_t)(void *user, size_t size); +typedef void *(*naxsi_mem_calloc_t)(void *user, size_t nmemb, size_t size); + +typedef struct naxsi_mem { + void *user; + naxsi_mem_free_t free; + naxsi_mem_malloc_t malloc; + naxsi_mem_calloc_t calloc; +} naxsi_mem_t; + +#define naxsi_memory(puser, pfree, pmalloc, pcalloc) \ + { (void *)puser, (naxsi_mem_free_t)pfree, (naxsi_mem_malloc_t)pmalloc, (naxsi_mem_calloc_t)pcalloc } + +typedef struct naxsi_config naxsi_config_t; + +#ifdef NAXSI_API +#undef NAXSI_API +#endif +#if defined(__GNUC__) && __GNUC__ >= 4 +#define NAXSI_API __attribute__((visibility("default"))) +#elif defined(_MSC_VER) +#define NAXSI_API __declspec(dllexport) +#else +#define NAXSI_API +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* NAXSI_TYPES_H */ diff --git a/libnaxsi/meson.build b/libnaxsi/meson.build new file mode 100644 index 0000000..1e3c786 --- /dev/null +++ b/libnaxsi/meson.build @@ -0,0 +1,89 @@ +project('libnaxsi', 'c', + version: '1.4.0', + license: 'GPL3', + meson_version: '>=0.59.0', + default_options: ['c_std=c99', 'buildtype=release', 'b_vscrt=from_buildtype'] +) +cc = meson.get_compiler('c') + +libnaxsi_c_args = [] +libnaxsi_deps = [] +libnaxsi_src = [ + 'src' / 'naxsi.c', + 'src' / 'naxsi_config.c', + 'src' / 'naxsi_list.c', + 'src' / 'naxsi_mem.c', + 'src' / 'naxsi_rule.c', + 'src' / 'naxsi_utils.c', +] +libnaxsi_includes = [ + 'include', + 'src' +] +libnaxsi_includes_installdir = get_option('includedir') / 'naxsi' + +pcre_sys = get_option('use_system_pcre') +pcre2_dep = dependency('libpcre2-posix', required: false) +pcre_dep = dependency('libpcre', required: false) +if pcre_sys and pcre2_dep.found() + libnaxsi_deps += pcre2_dep +elif pcre_sys and pcre_dep.found() + libnaxsi_deps += pcre_dep +else + libpcre2_proj = subproject('pcre2', default_options: ['default_library=static']) + libnaxsi_deps += libpcre2_proj.get_variable('libpcre2_posix') +endif + +libinjection_proj = subproject('libinjection', default_options: ['default_library=static'], required: true) +libnaxsi_deps += libinjection_proj.get_variable('libinjection_dep') + +if get_option('default_library') == 'shared' + if cc.has_argument('-fvisibility=hidden') + add_project_arguments('-fvisibility=hidden', language: 'c') + endif +endif + +libnaxsi = library('naxsi', libnaxsi_src, + c_args : libnaxsi_c_args, + dependencies: libnaxsi_deps, + implicit_include_directories: false, + install: true, + include_directories: include_directories(libnaxsi_includes) +) + +libnaxsi_dep = declare_dependency( + link_with: libnaxsi, + include_directories: include_directories(['include']), +) + +if get_option('enable_tests') and not meson.is_subproject() + tests_src_c = [ + 'utils', + 'mem', + 'list', + ] + tests_includes = [ + 'include', + 'src', + 'test', + ] + test_dependencies = [] + if get_option('b_sanitize').contains('address') + test_dependencies += cc.find_library('asan') + endif + if get_option('b_sanitize').contains('undefined') + test_dependencies += cc.find_library('ubsan') + endif + foreach test : tests_src_c + exe = executable('test_@0@'.format(test), 'test' / 'test_@0@.c'.format(test), + include_directories: include_directories(tests_includes), + sources: libnaxsi_src, + dependencies: test_dependencies, + c_args : libnaxsi_c_args, + install: false, + install_rpath: '', + implicit_include_directories: false + ) + test(test, exe) + endforeach +endif diff --git a/libnaxsi/meson_options.txt b/libnaxsi/meson_options.txt new file mode 100644 index 0000000..f7e1309 --- /dev/null +++ b/libnaxsi/meson_options.txt @@ -0,0 +1,2 @@ +option('use_system_pcre', type: 'boolean', value: true, description: 'Set to false when you want to use libpcre2 from the subproject') +option('enable_tests', type: 'boolean', value: true, description: 'Build unit tests in test/') diff --git a/libnaxsi/src/naxsi.c b/libnaxsi/src/naxsi.c new file mode 100644 index 0000000..ef2bb8b --- /dev/null +++ b/libnaxsi/src/naxsi.c @@ -0,0 +1,4 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include diff --git a/libnaxsi/src/naxsi_config.c b/libnaxsi/src/naxsi_config.c new file mode 100644 index 0000000..213dd14 --- /dev/null +++ b/libnaxsi/src/naxsi_config.c @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include "naxsi_config.h" +#include "naxsi_mem.h" + +/** + * @brief Allocates and initializes a naxsi_config_t structure + * + * @param memory The naxsi_mem_t structure to use for handling memory + * @param defaults_rules When enabled, adds the default rules into the configuration + * + * @return NULL if fails to allocate, otherwise non NULL. + */ +NAXSI_API naxsi_config_t *naxsi_config_new(const naxsi_mem_t *memory, bool defaults_rules) { + if (!memory) { + return NULL; + } + + naxsi_config_t *nctx = naxsi_mem_new(memory, naxsi_config_t); + if (!nctx) { + return NULL; + } + + nctx->rules = naxsi_list_new(memory, (naxsi_free_t)&naxsi_rule_free); + nctx->whitelist = naxsi_list_new(memory, (naxsi_free_t)&naxsi_whitelist_free); + if (!nctx->rules || !nctx->whitelist) { + naxsi_config_free(memory, nctx); + return NULL; + } + + return nctx; +} + +/** + * @brief Finalize and frees a naxsi_config_t pointer. + * + * @param memory The naxsi_mem_t structure to use for handling memory + * @param nctx The naxsi_config_t to free. + */ +NAXSI_API void naxsi_config_free(const naxsi_mem_t *memory, naxsi_config_t *nctx) { + if (!memory || !nctx) { + return; + } + naxsi_list_free(memory, nctx->rules); + naxsi_list_free(memory, nctx->whitelist); + naxsi_mem_free(memory, nctx); +} diff --git a/libnaxsi/src/naxsi_config.h b/libnaxsi/src/naxsi_config.h new file mode 100644 index 0000000..9cbedd7 --- /dev/null +++ b/libnaxsi/src/naxsi_config.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_CONFIG_H +#define NAXSI_CONFIG_H + +#include +#include "naxsi_list.h" +#include "naxsi_rule.h" + +typedef struct naxsi_config { + naxsi_list_t /**/ *rules; + naxsi_list_t /**/ *whitelist; +} naxsi_config_t; + +#endif /* NAXSI_CONFIG_H */ diff --git a/libnaxsi/src/naxsi_list.c b/libnaxsi/src/naxsi_list.c new file mode 100644 index 0000000..1d0ee43 --- /dev/null +++ b/libnaxsi/src/naxsi_list.c @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include "naxsi_list.h" + +/** + * @brief Allocates and initialize a new naxsi_list_t + * + * @param[in] memory The naxsi_mem_t structure to use + * @param[in] pfree The pointer to a naxsi_free_t + * + * @return Pointer to naxsi_list_t (NULL if fails) + */ +naxsi_list_t *naxsi_list_new(const naxsi_mem_t *memory, naxsi_free_t pfree) { + if (!memory) { + return NULL; + } + naxsi_list_t *list = naxsi_mem_new(memory, naxsi_list_t); + if (!list) { + return NULL; + } + list->free = pfree; + return list; +} + +/** + * @brief Appends a value to a naxsi_list_t + * + * @param[in] memory The naxsi_mem_t structure to use + * @param list The naxsi_list_t to append to + * @param value The value to append + * + * @return Pointer to naxsi_list_iter_t (NULL if fails) + */ +naxsi_list_iter_t *naxsi_list_append(const naxsi_mem_t *memory, naxsi_list_t *list, void *value) { + if (!memory || !list) { + return NULL; + } + naxsi_list_iter_t *item = naxsi_mem_new(memory, naxsi_list_iter_t); + if (!item) { + return item; + } + list->length++; + item->value = value; + if (list->tail) { + list->tail->next = item; + } + list->tail = item; + if (!list->head) { + list->head = item; + } + return item; +} + +/** + * @brief Frees a naxsi_list_t structure + * + * @param[in] memory The naxsi_mem_t structure to use + * @param list The naxsi_list_t pointer to free + */ +void naxsi_list_free(const naxsi_mem_t *memory, naxsi_list_t *list) { + if (!memory || !list) { + return; + } + naxsi_list_iter_t *iter = list->head; + while (iter) { + naxsi_list_iter_t *next = iter->next; + if (list->free) { + list->free(memory, iter->value); + } + naxsi_mem_free(memory, iter); + iter = next; + } + naxsi_mem_free(memory, list); +} diff --git a/libnaxsi/src/naxsi_list.h b/libnaxsi/src/naxsi_list.h new file mode 100644 index 0000000..85b191b --- /dev/null +++ b/libnaxsi/src/naxsi_list.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_LIST_H +#define NAXSI_LIST_H + +#include +#include "naxsi_mem.h" + +typedef struct naxsi_list_iter naxsi_list_iter_t; +typedef struct naxsi_list_iter { + naxsi_list_iter_t *next; + void *value; +} naxsi_list_iter_t; + +typedef struct naxsi_list { + size_t length; + naxsi_free_t free; + naxsi_list_iter_t *head; + naxsi_list_iter_t *tail; +} naxsi_list_t; + +#define naxsi_list_foreach(list, it, pos) \ + if (list) \ + for (it = list->head; it && (pos = it->data, 1); it = it->next) + +naxsi_list_t *naxsi_list_new(const naxsi_mem_t *memory, naxsi_free_t pfree); +naxsi_list_iter_t *naxsi_list_append(const naxsi_mem_t *memory, naxsi_list_t *list, void *data); +void naxsi_list_free(const naxsi_mem_t *memory, naxsi_list_t *list); + +#endif /* NAXSI_LIST_H */ diff --git a/libnaxsi/src/naxsi_mem.c b/libnaxsi/src/naxsi_mem.c new file mode 100644 index 0000000..c276fd5 --- /dev/null +++ b/libnaxsi/src/naxsi_mem.c @@ -0,0 +1,90 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include "naxsi_mem.h" + +/** + * @brief Frees the memory space pointed to by `pointer`. + * + * @param memory The naxsi_mem_t structure to use + * @param pointer The pointer to free (NULL pointers are accepted) + */ +void naxsi_mem_free(const naxsi_mem_t *memory, void *pointer) { + if (!pointer || !memory) { + return; + } + memory->free(memory->user, pointer); +} + +/** + * @brief Allocates memory of `size` bytes. + * + * @param memory The naxsi_mem_t structure to use + * @param[in] size The size of each element to allocate + * + * @return NULL if size is 0, otherwise the allocated pointer. + */ +void *naxsi_mem_malloc(const naxsi_mem_t *memory, size_t size) { + if (!size || !memory) { + return NULL; + } + return memory->malloc(memory->user, size); +} + +/** + * @brief Allocates memory for a zeroed array of `nmemb` elements of `size` bytes each. + * + * @param memory The naxsi_mem_t structure to use + * @param[in] nmemb The number of elements to allocate + * @param[in] size The size of each element to allocate + * + * @return NULL if size or nmemb is 0, otherwise the allocated pointer. + */ +void *naxsi_mem_calloc(const naxsi_mem_t *memory, size_t nmemb, size_t size) { + if (!size || !nmemb || !memory) { + return NULL; + } + return memory->calloc(memory->user, nmemb, size); +} + +/** + * @brief Allocates and initialize a new naxsi_str_t structure + * + * @param memory The naxsi_mem_t structure to use + * @param string The string to hold or to copy + * @param[in] length The string length + * @param[in] copy Set it to true to copy the string + * + * @return Pointer to naxsi_str_t or NULL + */ +naxsi_str_t *naxsi_str_new(const naxsi_mem_t *memory, char *string, size_t length, bool copy) { + if (!memory || !string || length < 1) { + return NULL; + } + naxsi_str_t *str = naxsi_mem_new(memory, naxsi_str_t); + if (!str) { + return NULL; + } + if (copy) { + str->data = naxsi_mem_malloc(memory, length + 1); + if (!str->data) { + naxsi_mem_free(memory, str); + return NULL; + } + memcpy(str->data, string, length + 1); + } else { + str->data = string; + } + str->length = length; + return str; +} + +void naxsi_str_free(const naxsi_mem_t *memory, naxsi_str_t *string, bool copy) { + if (!memory || !string) { + return; + } + if (copy) { + naxsi_mem_free(memory, string->data); + } + naxsi_mem_free(memory, string); +} diff --git a/libnaxsi/src/naxsi_mem.h b/libnaxsi/src/naxsi_mem.h new file mode 100644 index 0000000..2b9eb7c --- /dev/null +++ b/libnaxsi/src/naxsi_mem.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_MEM_H +#define NAXSI_MEM_H + +#include + +typedef void (*naxsi_free_t)(const naxsi_mem_t *memory, void *pointer); + +void naxsi_mem_free(const naxsi_mem_t *memory, void *pointer); +void *naxsi_mem_malloc(const naxsi_mem_t *memory, size_t size); +void *naxsi_mem_calloc(const naxsi_mem_t *memory, size_t nmemb, size_t size); +#define naxsi_mem_new(m, t) naxsi_mem_calloc(m, 1, sizeof(t)) + +naxsi_str_t *naxsi_str_new(const naxsi_mem_t *memory, char *string, size_t length, bool copy); +#define naxsi_mem_new2(m, s, c) naxsi_str_new(m, s, strlen(s), c) +void naxsi_str_free(const naxsi_mem_t *memory, naxsi_str_t *string, bool copy); + +#endif /* NAXSI_MEM_H */ diff --git a/libnaxsi/src/naxsi_rule.c b/libnaxsi/src/naxsi_rule.c new file mode 100644 index 0000000..09781dd --- /dev/null +++ b/libnaxsi/src/naxsi_rule.c @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include "naxsi_rule.h" + +naxsi_svector_define(scores, naxsi_score_t); +naxsi_vector_define(ids, u32); + +static void matchzone_free(const naxsi_mem_t *memory, naxsi_matchzone_t *matchzone) { + if (matchzone->args == NAXSI_MZ_TYPE_STRING) { + naxsi_str_free(memory, matchzone->args_val, true); + } else if (matchzone->args == NAXSI_MZ_TYPE_REGEX) { + // TODO free regex + } + if (matchzone->headers == NAXSI_MZ_TYPE_STRING) { + naxsi_str_free(memory, matchzone->headers_val, true); + } else if (matchzone->headers == NAXSI_MZ_TYPE_REGEX) { + // TODO free regex + } + if (matchzone->url == NAXSI_MZ_TYPE_STRING) { + naxsi_str_free(memory, matchzone->url_val, true); + } else if (matchzone->url == NAXSI_MZ_TYPE_REGEX) { + // TODO free regex + } +} + +void naxsi_rule_free(const naxsi_mem_t *memory, naxsi_rule_t *rule) { + if (!memory || !rule) { + return; + } + naxsi_str_free(memory, rule->description, true); + naxsi_scores_free(memory, rule->scores); + if (rule->mtype == NAXSI_MATCH_TYPE_STRING) { + naxsi_str_free(memory, (naxsi_str_t *)rule->match, true); + } else if (rule->mtype == NAXSI_MATCH_TYPE_REGEX) { + // TODO free regex + } + matchzone_free(memory, &rule->matchzone); + naxsi_mem_free(memory, rule); +} + +void naxsi_whitelist_free(const naxsi_mem_t *memory, naxsi_whitelist_t *whitelist) { + if (!memory || !whitelist) { + return; + } + naxsi_ids_free(memory, whitelist->ids); + matchzone_free(memory, &whitelist->matchzone); + naxsi_mem_free(memory, whitelist); +} diff --git a/libnaxsi/src/naxsi_rule.h b/libnaxsi/src/naxsi_rule.h new file mode 100644 index 0000000..5222dc2 --- /dev/null +++ b/libnaxsi/src/naxsi_rule.h @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_RULE_H +#define NAXSI_RULE_H + +#include +#include "naxsi_vector.h" + +#define naxsi_rule_has_flag(f, y) (f & y) + +typedef enum { + NAXSI_MATCH_TYPE_STRING /**/ = (1 << 0), ///< matches case-insensitive strings when "str:foo" is set + NAXSI_MATCH_TYPE_REGEX /* */ = (1 << 1), ///< matches case-insensitive strings when "rx:foo|bar" is set + NAXSI_MATCH_TYPE_XSS /* */ = (1 << 2), ///< matches case-insensitive strings when "d:libinj_xss" is set + NAXSI_MATCH_TYPE_SQL /* */ = (1 << 3), ///< matches case-insensitive strings when "d:libinj_sql" is set +} naxsi_mtype_t; + +typedef enum { + NAXSI_MZ_TYPE_UNSET /* */ = (0 << 0), ///< used only when the matchzone variable is unset + NAXSI_MZ_TYPE_GLOBAL /**/ = (1 << 0), ///< describes a global matchzone: BODY (parsed), URL, ARGS, HEADERS, FILE_EXT or RAW_BODY + NAXSI_MZ_TYPE_STRING /**/ = (1 << 1), ///< describes a specific matchzone: $URL, $ARGS_VAR, $HEADERS_VAR, $BODY_VAR + NAXSI_MZ_TYPE_REGEX /* */ = (1 << 2), ///< describes a regex matchzone: $URL_X, $ARGS_VAR_X, $HEADERS_VAR_X, $BODY_VAR_X +} naxsi_mz_type_t; + +typedef enum { + NAXSI_RULE_ACTION_SCORE /**/ = (0 << 0), ///< increments the scores when the rules matches + NAXSI_RULE_ACTION_BLOCK /**/ = (1 << 0), ///< directly blocks the request when the rule matches and is not in learning mode + NAXSI_RULE_ACTION_ALLOW /**/ = (1 << 1), ///< directly allows the request when the rule matches + NAXSI_RULE_ACTION_DROP /* */ = (1 << 2), ///< directly drop the request when the rule matches, regardless of the current mode + NAXSI_RULE_ACTION_LOG /* */ = (1 << 3), ///< directly logs the request when the rule matches +} naxsi_action_t; + +typedef struct naxsi_score { + naxsi_str_t name; ///< score name, for example: $ATTACK (s:$ATTACK:8) + u32 score; ///< score value to add to checkrule score, example: 8 (s:$ATTACK:8) +} naxsi_score_t; + +naxsi_svector(scores, naxsi_score_t); // naxsi_svector_t + +typedef struct naxsi_matchzone { + u8 args; ///< naxsi_mz_type_t which describes ARGS, $ARGS_VAR or $ARGS_VAR_X matchzone + u8 body; ///< naxsi_mz_type_t which describes BODY matchzone + u8 file_ext; ///< naxsi_mz_type_t which describes FILE_EXT matchzone + u8 headers; ///< naxsi_mz_type_t which describes ARGS, $ARGS_VAR or $ARGS_VAR_X matchzone + u8 raw_body; ///< naxsi_mz_type_t which describes RAW_BODY matchzone + u8 url; ///< naxsi_mz_type_t which describes URL, $URL or $URL_X matchzone + + void *args_val; ///< describes $ARGS_VAR:string or $ARGS_VAR_X:regex matchzone value + void *headers_val; ///< describes $ARGS_VAR:string or $ARGS_VAR_X:regex matchzone value + void *url_val; ///< describes $URL:string or $URL_X:regex matchzone value +} naxsi_matchzone_t; + +naxsi_vector(ids, u32); // naxsi_vector_t + +typedef struct naxsi_whitelist { + naxsi_ids_t *ids; ///< rule ids to whitelist, example: wl:10,32033,2000 + naxsi_matchzone_t matchzone; ///< matchzone to match when whitelisting, example: "mz:URL|BODY|ARGS" + bool negate; ///< negates the match result, so matching becomes not matching; example: negative +} naxsi_whitelist_t; + +typedef struct naxsi_rule { + naxsi_str_t *description; ///< describes the rule description, example: "msg:GIT-Homedir-Access" + u32 rule_id; ///< describes the rule id, example: id:42000329 + naxsi_action_t action; ///< describes an action instead of a score, example: s:DROP + naxsi_scores_t *scores; ///< describes the scores of the rule, example: s:$ATTACK:8,$UWA:8 + void *match; ///< describes a case-insensitive of string to match, or a regex or the libinjection XSS/SQL; example: "rx:^[a-zA-Z\d-]+$" or "str:/.git/" + naxsi_mtype_t mtype; ///< describes the type of match in the rule + naxsi_matchzone_t matchzone; ///< describes the matchzone of the rule, example: "mz:URL|BODY|ARGS" + bool negate; ///< negates the match result, so matching becomes not matching; example: negative +} naxsi_rule_t; + +void naxsi_rule_free(const naxsi_mem_t *memory, naxsi_rule_t *rule); +void naxsi_whitelist_free(const naxsi_mem_t *memory, naxsi_whitelist_t *whitelist); + +#endif /* NAXSI_RULE_H */ diff --git a/libnaxsi/src/naxsi_utils.c b/libnaxsi/src/naxsi_utils.c new file mode 100644 index 0000000..89be5e8 --- /dev/null +++ b/libnaxsi/src/naxsi_utils.c @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include "naxsi_utils.h" +#include +#include +#include + +/** + * @brief Search for the first occurrence of the given char (case sensitive) + * + * @param[in] string The input string + * @param[in] ch char to search + * @param[in] string_len The string length + * + * @return Pointer to the found char on the input string + */ +const char *naxsi_strnchr(const char *string, int ch, size_t string_len) { + for (size_t i = 0; i < string_len && string[i]; i++) { + if (string[i] == ch) { + return string + i; + } + } + return NULL; +} + +/** + * @brief Search for the first occurrence of the given char (case insensitive) + * + * @param[in] string The input string + * @param[in] ch char to search + * @param[in] string_len The string length + * + * @return Pointer to the found char on the input string + */ +static const char *strncasechr(const char *string, int ch, size_t string_len) { + for (size_t i = 0; i < string_len && string[i]; i++) { + if (tolower(string[i]) == ch) { + return string + i; + } + } + return NULL; +} + +/** + * @brief Checks if a string contains a certain substring + * + * @param[in] string The input string + * @param[in] string_len The string length + * @param[in] substring The substring to search + * @param[in] substring_len The substring length + * + * @return Pointer to the matched sequence or NULL if not found + */ +const char *naxsi_strstr_offset(naxsi_str_t *string, size_t offset, naxsi_str_t *substring) { + if (!string || !substring || string->length < 1 || substring->length < 1 || string->length < substring->length) { + return NULL; + } else if (substring->length == 1) { + return strncasechr(string->data, substring->data[0], string->length); + } + for (size_t i = offset; i < string->length; ++i) { + size_t leftover = string->length - i; + const char *found = strncasechr(string->data + i, substring->data[0], leftover); + if (!found) { + return NULL; + } else if (!strncasecmp(found + 1, substring->data + 1, substring->length - 1)) { + return found; + } + } + return NULL; +} + +/** + * @brief Converts all '\0' chars to '0' contained in a naxsi_str_t + * + * @param string The string to escape + * + * @return true if escapes any null bytes, otherwise false + */ +bool naxsi_escape_nullbytes(naxsi_str_t *string) { + bool found_null_byte = false; + for (size_t i = 0; i < string->length; i++) { + if (string->data[i] == 0) { + string->data[i] = '0'; + found_null_byte = true; + } + } + return found_null_byte; +} + +/** + * @brief Checks if naxsi_str_t contains a valid utf8 sequence + * Source: https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c + * + * @param string Pointer to naxsi_str_t containing string to test + * + * @return true when the string is a valid utf8 sequence, otherwise false + */ +bool naxsi_is_invalid_utf8(const naxsi_str_t *string) { + size_t offset = 0; + const unsigned char *s = (const unsigned char *)string->data; + size_t length = string->length; + while (offset < length && *s) { + if (*s < 0x80) { + /* 0xxxxxxx */ + s++; + offset++; + } else if ((s[0] & 0xe0) == 0xc0) { + if (offset + 1 >= length) { + // not enough bytes + return true; + } + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[0] & 0xfe) == 0xc0) { /* overlong? */ + return true; + } else { + s += 2; + offset += 2; + } + } else if ((s[0] & 0xf0) == 0xe0) { + if (offset + 2 >= length) { + // not enough bytes + return true; + } + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) { /* U+FFFE or U+FFFF? */ + return true; + } else { + s += 3; + } + } else if ((s[0] & 0xf8) == 0xf0) { + if (offset + 3 >= length) { + // not enough bytes + return true; + } + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) { /* > U+10FFFF? */ + return true; + } else { + s += 4; + } + } else { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/libnaxsi/src/naxsi_utils.h b/libnaxsi/src/naxsi_utils.h new file mode 100644 index 0000000..18928fc --- /dev/null +++ b/libnaxsi/src/naxsi_utils.h @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_UTILS_H +#define NAXSI_UTILS_H +#include + +bool naxsi_is_invalid_utf8(const naxsi_str_t *string); +bool naxsi_escape_nullbytes(naxsi_str_t *str); +const char *naxsi_strstr_offset(naxsi_str_t *string, size_t offset, naxsi_str_t *substring); +const char *naxsi_strnchr(const char *string, int ch, size_t string_len); + +#endif /* NAXSI_UTILS_H */ diff --git a/libnaxsi/src/naxsi_vector.h b/libnaxsi/src/naxsi_vector.h new file mode 100644 index 0000000..365f0f0 --- /dev/null +++ b/libnaxsi/src/naxsi_vector.h @@ -0,0 +1,179 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef NAXSI_VECTOR_H +#define NAXSI_VECTOR_H + +#include +#include "naxsi_mem.h" + +/* vector of native types */ +#define naxsi_vector(name, type) \ + typedef struct naxsi_##name##_s { \ + type *data; \ + size_t length; \ + } naxsi_##name##_t; \ +\ + naxsi_##name##_t *naxsi_##name##_new(const naxsi_mem_t *memory, size_t length); \ + void naxsi_##name##_free(const naxsi_mem_t *memory, naxsi_##name##_t *vec); \ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type value); \ + type naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type def_value) + +/* vector of structs */ +#define naxsi_svector(name, type) \ + typedef struct naxsi_##name##_s { \ + type *data; \ + size_t length; \ + } naxsi_##name##_t; \ +\ + naxsi_##name##_t *naxsi_##name##_new(const naxsi_mem_t *memory, size_t length); \ + void naxsi_##name##_free(const naxsi_mem_t *memory, naxsi_##name##_t *vec); \ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type *value); \ + type *naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type *def_value) + +/* vector of pointers */ +#define naxsi_pvector(name, type) \ + typedef struct naxsi_##name##_s { \ + type **data; \ + size_t length; \ + naxsi_free_t free; \ + } naxsi_##name##_t; \ +\ + naxsi_##name##_t *naxsi_##name##_new(const const naxsi_mem_t *memory, size_t length, naxsi_free_t pfree); \ + void naxsi_##name##_free(const const naxsi_mem_t *memory, naxsi_##name##_t *vec); \ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type *value); \ + type *naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type *def_value) + +/* vector of native types */ +#define naxsi_vector_define(name, type) \ + naxsi_##name##_t *naxsi_##name##_new(const naxsi_mem_t *memory, size_t length) { \ + if (!memory || length < 1) { \ + return NULL; \ + } \ + naxsi_##name##_t *vec = naxsi_mem_new(memory, naxsi_##name##_t); \ + if (!vec) { \ + return NULL; \ + } \ + vec->length = length; \ + vec->data = naxsi_mem_calloc(memory, length, sizeof(type)); \ + if (!vec->data) { \ + naxsi_mem_free(memory, vec); \ + return NULL; \ + } \ + return vec; \ + } \ +\ + void naxsi_##name##_free(const naxsi_mem_t *memory, naxsi_##name##_t *vec) { \ + if (!memory || !vec) { \ + return; \ + } \ + naxsi_mem_free(memory, vec->data); \ + naxsi_mem_free(memory, vec); \ + } \ +\ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type value) { \ + if (!vec || index >= vec->length) { \ + return false; \ + } \ + vec->data[index] = value; \ + return true; \ + } \ +\ + type naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type def_value) { \ + if (!vec || index >= vec->length) { \ + return def_value; \ + } \ + return vec->data[index]; \ + } + +/* vector of structs */ +#define naxsi_svector_define(name, type) \ + naxsi_##name##_t *naxsi_##name##_new(const naxsi_mem_t *memory, size_t length) { \ + if (!memory || length < 1) { \ + return NULL; \ + } \ + naxsi_##name##_t *vec = naxsi_mem_new(memory, naxsi_##name##_t); \ + if (!vec) { \ + return NULL; \ + } \ + vec->length = length; \ + vec->data = naxsi_mem_calloc(memory, length, sizeof(type)); \ + if (!vec->data) { \ + naxsi_mem_free(memory, vec); \ + return NULL; \ + } \ + return vec; \ + } \ +\ + void naxsi_##name##_free(const naxsi_mem_t *memory, naxsi_##name##_t *vec) { \ + if (!memory || !vec) { \ + return; \ + } \ + naxsi_mem_free(memory, vec->data); \ + naxsi_mem_free(memory, vec); \ + } \ +\ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type *value) { \ + if (!vec || index >= vec->length) { \ + return false; \ + } \ + vec->data[index] = *value; \ + return true; \ + } \ +\ + type *naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type *def_value) { \ + if (!vec || index >= vec->length) { \ + return def_value; \ + } \ + return &vec->data[index]; \ + } + +/* vector of pointers */ +#define naxsi_pvector_define(name, type) \ + naxsi_##name##_t *naxsi_##name##_new(const const naxsi_mem_t *memory, size_t length, naxsi_##name##_free_t pfree) { \ + if (!memory || length < 1) { \ + return NULL; \ + } \ + naxsi_##name##_t *vec = naxsi_mem_new(memory, naxsi_##name##_t); \ + if (!vec) { \ + return NULL; \ + } \ + vec->free = pfree; \ + vec->length = length; \ + vec->data = naxsi_mem_calloc(memory, length, sizeof(type *)); \ + if (!vec->data) { \ + naxsi_mem_free(memory, vec); \ + vec = NULL; \ + } \ + return vec; \ + } \ +\ + void naxsi_##name##_free(const const naxsi_mem_t *memory, naxsi_##name##_t *vec) { \ + if (!memory || !vec) { \ + return; \ + } \ + if (vec->free) { \ + for (size_t i = 0; i < vec->length; ++i) { \ + vec->free(memory, vec->data[i]); \ + } \ + } \ + naxsi_mem_free(memory, vec->data); \ + naxsi_mem_free(memory, vec); \ + } \ +\ + bool naxsi_##name##_set_at(naxsi_##name##_t *vec, size_t index, type *value) { \ + if (!vec || index >= vec->length) { \ + return false; \ + } \ + vec->data[index] = value; \ + return true; \ + } \ +\ + type *naxsi_##name##_get_at(naxsi_##name##_t *vec, size_t index, type *def_value) { \ + if (!vec || index >= vec->length) { \ + return def_value; \ + } \ + return vec->data[index]; \ + } + +#endif /* NAXSI_VECTOR_H */ diff --git a/libnaxsi/subprojects/libinjection.wrap b/libnaxsi/subprojects/libinjection.wrap new file mode 100644 index 0000000..aa1c529 --- /dev/null +++ b/libnaxsi/subprojects/libinjection.wrap @@ -0,0 +1,4 @@ +[wrap-git] +url = https://github.com/libinjection/libinjection.git +revision = 49904c42a6e68dc8f16c022c693e897e4010a06c +patch_directory = libinjection \ No newline at end of file diff --git a/libnaxsi/subprojects/packagefiles/libinjection/meson.build b/libnaxsi/subprojects/packagefiles/libinjection/meson.build new file mode 100644 index 0000000..038b20c --- /dev/null +++ b/libnaxsi/subprojects/packagefiles/libinjection/meson.build @@ -0,0 +1,27 @@ +project('libinjection', 'c', + license: ['BSD-3-Clause'], + default_options : ['c_std=c99', 'buildtype=release', 'b_vscrt=from_buildtype'], + version: '49904c42a6e68dc8f16c022c693e897e4010a06c', + meson_version: '>=0.59.0' +) + +libinjection_files = [ + 'src' / 'libinjection_sqli.c', + 'src' / 'libinjection_xss.c', + 'src' / 'libinjection_html5.c', +] + +libinjection_includes = [ + 'src', +] + +libinjection = library('injection', libinjection_files, + include_directories: include_directories(libinjection_includes), + implicit_include_directories: false, + install: false, +) + +libinjection_dep = declare_dependency( + link_with: libinjection, + include_directories: libinjection_includes, +) diff --git a/libnaxsi/subprojects/packagefiles/pcre2/meson.build b/libnaxsi/subprojects/packagefiles/pcre2/meson.build new file mode 100644 index 0000000..dc65f3a --- /dev/null +++ b/libnaxsi/subprojects/packagefiles/pcre2/meson.build @@ -0,0 +1,93 @@ +project('pcre2', 'c', + license: ['BSD-3-Clause'], + default_options : ['c_std=c99', 'buildtype=release', 'b_vscrt=from_buildtype'], + version: '10.39', + meson_version: '>=0.59.0' +) + +c_compiler = meson.get_compiler('c') +pcre2_h = configure_file(input : 'src/pcre2.h.generic', output : 'pcre2.h', copy: true) +chartables = configure_file(input : 'src/pcre2_chartables.c.dist', output : 'pcre2_chartables.c', copy: true) +config_h = configure_file(input : 'src/config.h.generic', output : 'config.h', copy: true) + +sources = [ + 'src' / 'pcre2_auto_possess.c', + chartables, + config_h, pcre2_h, + 'src' / 'pcre2_compile.c', + 'src' / 'pcre2_config.c', + 'src' / 'pcre2_context.c', + 'src' / 'pcre2_dfa_match.c', + 'src' / 'pcre2_error.c', + 'src' / 'pcre2_find_bracket.c', + 'src' / 'pcre2_jit_compile.c', + 'src' / 'pcre2_maketables.c', + 'src' / 'pcre2_match.c', + 'src' / 'pcre2_match_data.c', + 'src' / 'pcre2_newline.c', + 'src' / 'pcre2_ord2utf.c', + 'src' / 'pcre2_pattern_info.c', + 'src' / 'pcre2_serialize.c', + 'src' / 'pcre2_string_utils.c', + 'src' / 'pcre2_study.c', + 'src' / 'pcre2_substitute.c', + 'src' / 'pcre2_substring.c', + 'src' / 'pcre2_tables.c', + 'src' / 'pcre2_ucd.c', + 'src' / 'pcre2_valid_utf.c', + 'src' / 'pcre2_xclass.c' +] + +includes = [include_directories('.'), include_directories('src')] + +check_headers = [ + ['HAVE_INTTYPES_H', 'inttypes.h'], + ['HAVE_BZLIB_H', 'bzlib.h'], + ['HAVE_SYS_STAT_H', 'sys/stat.h'], + ['HAVE_SYS_TYPES_H', 'sys/types.h'], + ['HAVE_SYS_WAIT_H', 'sys/wait.h'], + ['HAVE_INTTYPES_H', 'inttypes.h'], + ['HAVE_DIRENT_H', 'dirent.h'], + ['HAVE_DLFCN_H', 'dlfcn.h'], + ['HAVE_LIMITS_H', 'limits.h'], + ['HAVE_STDINT_H', 'stdint.h'], + ['HAVE_STDLIB_H', 'stdlib.h'], + ['HAVE_STRING_H', 'string.h'], + ['HAVE_WINDOWS_H', 'windows.h'], + ['HAVE_UNISTD_H', 'unistd.h'] +] + +config_h_defs = [] +foreach h : check_headers + if c_compiler.has_header(h.get(1)) + config_h_defs += ['-D' + h.get(0)] + endif +endforeach + +check_funs = [ + ['HAVE_STRERROR', 'strerror'], +] + +foreach f : check_funs + if c_compiler.has_function(f.get(1)) + config_h_defs += ['-D' + f.get(0)] + endif +endforeach + +config_h_defs += ['-DHAVE_MEMMOVE', '-DSTDC_HEADERS', '-DSUPPORT_PCRE2_8', '-DSUPPORT_UNICODE'] + +pcre2_8_lib = library('pcre2-8', sources, + include_directories: includes, + c_args: config_h_defs + ['-DHAVE_CONFIG_H', '-DPCRE2_CODE_UNIT_WIDTH=8'], + install: true) + +pcre2_posix_lib = library('pcre2-posix', ['src/pcre2posix.c', 'src/pcre2posix.h'], + include_directories: includes, + link_with: pcre2_8_lib, + c_args: config_h_defs + ['-DHAVE_CONFIG_H', '-DPCRE2_CODE_UNIT_WIDTH=8'], + install: true) + +libpcre2_posix = declare_dependency(link_with: pcre2_posix_lib, + include_directories: includes) + +install_headers([pcre2_h, 'src' / 'pcre2posix.h']) diff --git a/libnaxsi/subprojects/pcre2.wrap b/libnaxsi/subprojects/pcre2.wrap new file mode 100644 index 0000000..6c9d741 --- /dev/null +++ b/libnaxsi/subprojects/pcre2.wrap @@ -0,0 +1,4 @@ +[wrap-git] +url = https://github.com/PhilipHazel/pcre2.git +revision = pcre2-10.39 +patch_directory = pcre2 diff --git a/libnaxsi/test/minunit.h b/libnaxsi/test/minunit.h new file mode 100644 index 0000000..9c94f7a --- /dev/null +++ b/libnaxsi/test/minunit.h @@ -0,0 +1,293 @@ +// SPDX-FileCopyrightText: 2015 Jeffrey Crowell +// SPDX-FileCopyrightText: 2018 ret2libc +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +// minunit.h comes from http://www.jera.com/techinfo/jtns/jtn002.html +// +// You may use the code in this tech note for any purpose, +// with the understanding that it comes with NO WARRANTY. + +#ifndef _MINUNIT_H_ +#define _MINUNIT_H_ +#include +#include +#include + +#if __WINDOWS__ +#define TRED +#define TGREEN +#define TYELLOW +#define TBLUE +#define TMAGENTA +#define TCYAN +#define TBOLD +#define TRESET +#else +#define TRED "\x1b[31m" +#define TGREEN "\x1b[32m" +#define TYELLOW "\x1b[33m" +#define TBLUE "\x1b[34m" +#define TMAGENTA "\x1b[35m" +#define TCYAN "\x1b[36m" +#define TBOLD "\x1b[1m" +#define TRESET "\x1b[0m" +#endif + +#define MU_PASSED 1 +#define MU_ERR 0 + +#define MU_TEST_UNBROKEN 0 +#define MU_TEST_BROKEN 1 + +#define MU_BUF_SIZE 5120 + +void snprint_mem(char *out, size_t out_size, const unsigned char *buf, size_t len) { + size_t i; + *out = '\0'; + for (i = 0; i < len; i++) { + size_t out_len; + if (i > 0) { + out_len = strlen(out); + snprintf(out + out_len, out_size - out_len, " "); + } + out_len = strlen(out); + snprintf(out + out_len, out_size - out_len, "%02x", buf[i]); + } +} + +#define mu_assert(message, test) \ + do { \ + if (!(test)) { \ + mu_fail(message); \ + mu_test_status = MU_TEST_UNBROKEN; \ + } \ + } while (0) + +#define mu_perror(message) \ + do { \ + if (mu_test_status != MU_TEST_BROKEN) { \ + printf(TBOLD TRED "ERR\n[XX] Fail at line %d: " TRESET "%s\n\n", __LINE__, message); \ + } else { \ + printf(TBOLD TYELLOW "Broken at line %d: " TRESET "%s\n\n", __LINE__, message); \ + } \ + } while (0) + +#define mu_psyserror(message) \ + do { \ + perror(message); \ + mu_perror(message); \ + } while (0) + +#define mu_fail(message) \ + do { \ + mu_perror(message); \ + if (mu_test_status != MU_TEST_BROKEN) \ + return MU_ERR; \ + } while (0) + +#define mu_ignore \ + do { \ + printf(TYELLOW "IGN\n" TRESET); \ + return MU_PASSED; \ + } while (0) + +#define mu_end \ + do { \ + printf(TGREEN "OK\n" TRESET); \ + return MU_PASSED; \ + } while (0) + +#define mu_cleanup_end \ + do { \ + if (retval == MU_PASSED) { \ + mu_end; \ + } else { \ + return retval; \ + } \ + } while (0) + +#define mu_sysfail(message) \ + do { \ + perror(message); \ + mu_fail(message); \ + } while (0) + +#define mu_assert_true(actual, message) \ + do { \ + bool act__ = (actual); \ + if (!(act__)) { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected true, got false", (message)); \ + mu_assert(_meqstr, false); \ + } \ + } while (0) + +#define mu_assert_false(actual, message) \ + do { \ + bool act__ = (actual); \ + if ((act__)) { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected false, got true", (message)); \ + mu_assert(_meqstr, false); \ + } \ + } while (0) + +#define mu_assert_eq(actual, expected, message) \ + do { \ + if ((expected) != (actual)) { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected %" PFMT64u ", got %" PFMT64u ".", (message), (expected), (actual)); \ + mu_assert(_meqstr, false); \ + } \ + } while (0) + +#define mu_assert_eqf(actual, expected, message) \ + do { \ + double act__ = (double)(actual); \ + double exp__ = (double)(expected); \ + if ((exp__) != (act__)) { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected %lf, got %lf.", (message), exp__, act__); \ + mu_assert(_meqstr, false); \ + } \ + } while (0) + +#define mu_assert_neq(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected not %" PFMT64u ", got %" PFMT64u ".", (message), (expected), (actual)); \ + mu_assert(_meqstr, (expected) != (actual)); \ + } while (0) + +#define mu_assert_ptreq(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const void *act__ = (actual); \ + const void *exp__ = (expected); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected %p, got %p.", (message), (exp__), (act__)); \ + mu_assert(_meqstr, (exp__) == (act__)); \ + } while (0) + +#define mu_assert_ptrneq(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const void *act__ = (actual); \ + const void *exp__ = (expected); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected not %p, got %p.", (message), (exp__), (act__)); \ + mu_assert(_meqstr, (exp__) != (act__)); \ + } while (0) + +#define mu_assert_null(actual, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const void *act__ = (actual); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected to be NULL but it wasn't.", (message)); \ + mu_assert(_meqstr, (act__) == NULL); \ + } while (0) + +#define mu_assert_notnull(actual, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const void *act__ = (actual); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected to not be NULL but it was.", (message)); \ + mu_assert(_meqstr, (act__) != NULL); \ + } while (0) + +#define mu_assert_eq_fmt(actual, expected, message, fmt) \ + do { \ + if ((actual) != (expected)) { \ + char _meqstr[MU_BUF_SIZE]; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected " fmt ", got " fmt ".", (message), (actual), (expected)); \ + mu_assert(_meqstr, false); \ + } \ + } while (0) + +#define mu_assert_streq(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const char *act__ = (actual); \ + act__ = act__ ? act__ : "(null)"; \ + const char *exp__ = (expected); \ + exp__ = exp__ ? exp__ : "(null)"; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected %s, got %s.", (message), (exp__), (act__)); \ + mu_assert(_meqstr, strcmp((exp__), (act__)) == 0); \ + } while (0) + +#define mu_assert_strcontains(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const char *act__ = (actual); \ + act__ = act__ ? act__ : "(null)"; \ + const char *exp__ = (expected); \ + exp__ = exp__ ? exp__ : "(null)"; \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected to find %s in %s.", (message), (exp__), (act__)); \ + mu_assert(_meqstr, strstr((act__), (exp__)) != NULL); \ + } while (0) + +#define mu_assert_streq_free(actual, expected, message) \ + do { \ + char *act2__ = (actual); \ + mu_assert_streq(act2__, (expected), (message)); \ + free(act2__); \ + } while (0) + +#define mu_assert_nullable_streq(actual, expected, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + const char *act__ = (actual); \ + const char *exp__ = (expected); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected %s, got %s.", (message), (exp__ ? exp__ : "NULL"), (act__ ? act__ : "NULL")); \ + mu_assert(_meqstr, ((act__) == NULL && (exp__) == NULL) || ((act__) != NULL && (exp__) != NULL && strcmp((exp__), (act__)) == 0)); \ + } while (0) + +#define mu_assert_memeq(actual, expected, len, message) \ + do { \ + char _meqstr[MU_BUF_SIZE]; \ + size_t _meqstr_len; \ + const unsigned char *act__ = (actual); \ + const unsigned char *exp__ = (expected); \ + snprintf(_meqstr, MU_BUF_SIZE, "%s: expected ", message); \ + _meqstr_len = strlen(_meqstr); \ + snprint_mem(_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, (exp__), (len)); \ + _meqstr_len = strlen(_meqstr); \ + snprintf(_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, ", got "); \ + _meqstr_len = strlen(_meqstr); \ + snprint_mem(_meqstr + _meqstr_len, MU_BUF_SIZE - _meqstr_len, (act__), (len)); \ + mu_assert(_meqstr, memcmp((exp__), (act__), (len)) == 0); \ + } while (0) + +#define mu_run_test_named(test, name, ...) \ + do { \ + int result; \ + printf(TBOLD "%s" TRESET " ", name); \ + mu_test_status = MU_TEST_UNBROKEN; \ + result = test(__VA_ARGS__); \ + tests_run++; \ + tests_passed += result; \ + } while (0) + +#define mu_run_test(test, ...) mu_run_test_named(test, #test, __VA_ARGS__) + +#define mu_cleanup_fail(label, message) \ + do { \ + mu_perror(message); \ + retval = MU_ERR; \ + goto label; \ + } while (0) +#define mu_cleanup_sysfail(label, message) \ + do { \ + mu_psyserror(message); \ + retval = MU_ERR; \ + goto label; \ + } while (0) +int tests_run = 0; +int tests_passed = 0; +int mu_test_status = MU_TEST_UNBROKEN; + +#define mu_main(fcn) \ + int main(int argc, char **argv) { \ + return fcn(); \ + } + +#endif diff --git a/libnaxsi/test/minunit_mem.h b/libnaxsi/test/minunit_mem.h new file mode 100644 index 0000000..db132ef --- /dev/null +++ b/libnaxsi/test/minunit_mem.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only +#ifndef MU_MEMORY +#define MU_MEMORY +#include "minunit.h" +#include + +#define mu_naxsi_mem() naxsi_memory(NULL, &mu_free, &mu_malloc, &mu_calloc) + +static void mu_free(void *unused, void *pointer) { + (void)unused; + free(pointer); +} + +static void *mu_malloc(void *unused, size_t size) { + (void)unused; + return malloc(size); +} + +static void *mu_calloc(void *unused, size_t nmemb, size_t size) { + (void)unused; + return calloc(nmemb, size); +} + +#endif /* MU_MEMORY */ diff --git a/libnaxsi/test/test_list.c b/libnaxsi/test/test_list.c new file mode 100644 index 0000000..d721b24 --- /dev/null +++ b/libnaxsi/test/test_list.c @@ -0,0 +1,100 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only +#include "minunit_mem.h" +#include "naxsi_list.h" + +typedef struct test_s { + int padding; +} test_s_t; + +static void test_s_free(const naxsi_mem_t *memory, void *p) { + naxsi_mem_free(memory, p); +} + +bool test_naxsi_list(void) { + test_s_t *elem; + naxsi_list_t *list; + naxsi_list_iter_t *iter; + naxsi_mem_t mem = mu_naxsi_mem(); + + /* test invalid allocation */ + + list = naxsi_list_new(NULL, NULL); + mu_assert_null(list, "naxsi_list_new(NULL, NULL) shall return NULL"); + + list = naxsi_list_new(NULL, (naxsi_free_t)43); + mu_assert_null(list, "naxsi_list_new(NULL, 43) shall return NULL"); + + /* test valid allocation */ + + list = naxsi_list_new(&mem, NULL); + mu_assert_notnull(list, "naxsi_list_new(&mem, NULL) shall not return NULL"); + mu_assert_null(list->head, "list->head shall not be NULL"); + mu_assert_null(list->tail, "list->tail shall not be NULL"); + mu_assert_eq_fmt(list->length, 0lu, "list->length shall be 0", "%lu"); + mu_assert_null(list->free, "list->free shall not be NULL"); + naxsi_list_free(&mem, list); + + /* test with custom free function */ + + list = naxsi_list_new(&mem, (naxsi_free_t)&test_s_free); + mu_assert_notnull(list, "naxsi_list_new(&mem, test_s_free) shall not return NULL"); + mu_assert_null(list->head, "list->head shall not be NULL"); + mu_assert_null(list->tail, "list->tail shall not be NULL"); + mu_assert_eq_fmt(list->length, 0lu, "list->length shall be 0", "%lu"); + mu_assert_ptreq(list->free, &test_s_free, "list->free shall be test_s_free"); + + elem = naxsi_mem_new(&mem, test_s_t); + mu_assert_notnull(elem, "naxsi_mem_new(&mem, test_s_t) shall not return NULL"); + + iter = naxsi_list_append(NULL, NULL, NULL); + mu_assert_null(iter, "naxsi_list_append(NULL, NULL, NULL) shall return NULL"); + + iter = naxsi_list_append(NULL, (naxsi_list_t *)42, NULL); + mu_assert_null(iter, "naxsi_list_append(NULL, 42, NULL) shall return NULL"); + + iter = naxsi_list_append((naxsi_mem_t *)42, NULL, NULL); + mu_assert_null(iter, "naxsi_list_append(42, NULL, NULL) shall return NULL"); + + iter = naxsi_list_append(&mem, list, NULL); + mu_assert_notnull(iter, "naxsi_list_append(&mem, list, NULL) shall not return NULL"); + mu_assert_eq_fmt(list->length, 1lu, "list->length shall be 1", "%lu"); + mu_assert_ptreq(list->tail, iter, "list->tail shall be iter"); + mu_assert_ptreq(list->head, iter, "list->tail shall be iter"); + + iter = naxsi_list_append(&mem, list, elem); + mu_assert_notnull(iter, "naxsi_list_append(&mem, list, elem) shall not return NULL"); + mu_assert_eq_fmt(list->length, 2lu, "list->length shall be 2", "%lu"); + mu_assert_ptreq(list->tail, iter, "list->tail shall be iter"); + mu_assert_ptrneq(list->head, iter, "list->tail shall not be iter"); + mu_assert_null(iter->next, "iter->next shall not be iter"); + + naxsi_list_free(&mem, list); + + /* test with without free function */ + + list = naxsi_list_new(&mem, NULL); + mu_assert_notnull(list, "naxsi_list_new(&mem, NULL) shall not return NULL"); + + iter = naxsi_list_append(&mem, list, NULL); + mu_assert_notnull(iter, "naxsi_list_append(&mem, list, NULL) shall not return NULL"); + mu_assert_eq_fmt(list->length, 1lu, "list->length shall be 1", "%lu"); + + iter = naxsi_list_append(&mem, list, (void *)42); + mu_assert_notnull(iter, "naxsi_list_append(&mem, list, elem) shall not return NULL"); + mu_assert_eq_fmt(list->length, 2lu, "list->length shall be 2", "%lu"); + + iter = naxsi_list_append(&mem, list, (void *)43); + mu_assert_notnull(iter, "naxsi_list_append(&mem, list, elem) shall not return NULL"); + mu_assert_eq_fmt(list->length, 3lu, "list->length shall be 3", "%lu"); + + naxsi_list_free(&mem, list); + mu_end; +} + +int all_tests() { + mu_run_test(test_naxsi_list); + return tests_passed != tests_run; +} + +mu_main(all_tests) diff --git a/libnaxsi/test/test_mem.c b/libnaxsi/test/test_mem.c new file mode 100644 index 0000000..e668f6d --- /dev/null +++ b/libnaxsi/test/test_mem.c @@ -0,0 +1,110 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only +#include "minunit.h" +#include "naxsi_mem.h" +#include + +static bool malloc_called = false; +static bool calloc_called = false; +static void *free_called = 0; +static void *free_user = 0; + +#define mu_test_naxsi_mem() naxsi_memory(42, &test_free, &test_malloc, &test_calloc) + +static void test_free(void *user, void *pointer) { + free(pointer); + free_called = pointer; + free_user = user; +} + +static void *test_malloc(void *user, size_t size) { + malloc_called = true; + if (user) { + return malloc(size); + } + return NULL; +} + +static void *test_calloc(void *user, size_t nmemb, size_t size) { + calloc_called = true; + if (user) { + return calloc(nmemb, size); + } + return NULL; +} + +bool test_naxsi_mem_malloc(void) { + naxsi_mem_t mem = mu_test_naxsi_mem(); + void *ptr = NULL; + + malloc_called = false; + ptr = naxsi_mem_malloc(NULL, 10); + mu_assert_null(ptr, "naxsi_mem_malloc(NULL, 10) shall return NULL"); + mu_assert_false(calloc_called, "verify that memory->malloc is not called"); + + ptr = naxsi_mem_malloc(&mem, 0); + mu_assert_null(ptr, "naxsi_mem_malloc(&mem, 0) shall return NULL"); + + ptr = naxsi_mem_malloc(&mem, 10); + mu_assert_notnull(ptr, "naxsi_mem_malloc(&mem, 10) shall return not NULL"); + free(ptr); + + mem.user = NULL; + ptr = naxsi_mem_malloc(&mem, 10); + mu_assert_null(ptr, "verify that void *user is passed to memory->malloc"); + + mu_end; +} + +bool test_naxsi_mem_calloc(void) { + naxsi_mem_t mem = mu_test_naxsi_mem(); + void *ptr = NULL; + + calloc_called = false; + ptr = naxsi_mem_calloc(NULL, 10, 10); + mu_assert_null(ptr, "naxsi_mem_calloc(NULL, 10, 10) shall return NULL"); + mu_assert_false(calloc_called, "verify that memory->calloc is not called"); + + ptr = naxsi_mem_calloc(&mem, 10, 0); + mu_assert_null(ptr, "naxsi_mem_calloc(&mem, 10, 0) shall return NULL"); + + ptr = naxsi_mem_calloc(&mem, 1, 10); + mu_assert_notnull(ptr, "naxsi_mem_calloc(&mem, 10) shall return not NULL"); + mu_assert_memeq(ptr, (const void *)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10, "naxsi_mem_calloc(10) shall be set to zero"); + free(ptr); + + mem.user = NULL; + ptr = naxsi_mem_calloc(&mem, 10, 10); + mu_assert_null(ptr, "verify that void *user is passed to memory->calloc"); + + mu_end; +} + +bool test_naxsi_mem_free(void) { + naxsi_mem_t mem = mu_test_naxsi_mem(); + void *ptr = NULL; + + free_called = NULL; + free_user = NULL; + ptr = naxsi_mem_malloc(&mem, 10); + naxsi_mem_free(&mem, ptr); + mu_assert_notnull(free_called, "verify that free has been called"); + mu_assert_notnull(free_user, "verify that void *user is passed to free"); + + free_called = (void *)32; + naxsi_mem_free(&mem, NULL); + mu_assert_ptreq(free_called, (void *)32, "naxsi_mem_free(&mem, NULL) shall not call memory->free"); + naxsi_mem_free(NULL, (void *)55); + mu_assert_ptreq(free_called, (void *)32, "naxsi_mem_free(NULL, 55) shall not call memory->free"); + + mu_end; +} + +int all_tests() { + mu_run_test(test_naxsi_mem_malloc); + mu_run_test(test_naxsi_mem_calloc); + mu_run_test(test_naxsi_mem_free); + return tests_passed != tests_run; +} + +mu_main(all_tests) diff --git a/libnaxsi/test/test_utils.c b/libnaxsi/test/test_utils.c new file mode 100644 index 0000000..98a1f97 --- /dev/null +++ b/libnaxsi/test/test_utils.c @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only +#include "minunit.h" +#include "naxsi_utils.h" +#include + +#define mu_assert_utf8(a, e, m) \ + do { \ + naxsi_str_t _input; \ + _input.data = (a); \ + _input.length = sizeof(a) - 1; \ + bool _r = naxsi_is_invalid_utf8(&_input); \ + mu_assert("utf8: " m, _r == e); \ + } while (0) + +#define mu_assert_strstr_offset(a, o, b, e, m) \ + do { \ + naxsi_str_t _input = naxsi_string(a); \ + naxsi_str_t _substr = naxsi_string(b); \ + const char *_x = naxsi_strstr_offset(&_input, (o), &_substr); \ + mu_assert_ptreq(_x, (e) ? ((a) + (e)) : NULL, (m)); \ + } while (0) + +#define mu_assert_strnchr(a, b, e, m) \ + do { \ + size_t _l = strlen(a); \ + const char *_x = naxsi_strnchr((a), (b), _l); \ + mu_assert_ptreq(_x, (e) ? ((a) + (e)) : NULL, "strnchr: " m); \ + } while (0) + +bool test_naxsi_escape_nullbytes(void) { + int i, count = 0; + naxsi_str_t input; + input.data = malloc(32); + + // apply null bytes twice + memcpy(input.data, "with\x00 nullbytes\x00 here", 22); + input.length = 21; + mu_assert_true(naxsi_escape_nullbytes(&input), "has escaped null bytes"); + for (i = 0, count = 0; i < input.length; ++i) { + if (input.data[i] == '0') { + count++; + } + } + mu_assert_eq_fmt(count, 2, "escaped 2 null bytes", "%u"); + mu_assert_true(input.data[4] == '0', "escape null byte at 4"); + mu_assert_true(input.data[15] == '0', "escape null byte at 15"); + + // fail because there are no null byte + strcpy(input.data, "no nullbytes here"); + input.length = strlen(input.data); + mu_assert_false(naxsi_escape_nullbytes(&input), "has not escaped null bytes"); + for (i = 0, count = 0; i < input.length; ++i) { + if (input.data[i] == '0') { + count++; + } + } + mu_assert_eq_fmt(count, 0, "escaped 0 null bytes", "%u"); + + free(input.data); + mu_end; +} + +bool test_naxsi_strstr_offset(void) { + mu_assert_strstr_offset("test this strstr @ function", 0, "strstr", 10u, "strstr is in string"); + mu_assert_strstr_offset("test this strstr @ function", 11, "strstr", 0u, "strstr is NOT in string when offset is 11"); + mu_assert_strstr_offset("a", 0, "aaaa", 0u, "cannot find a substring in a smaller string"); + mu_assert_strstr_offset("", 0, "bbbbb", 0u, "cannot find a substring in a empty string"); + mu_assert_strstr_offset("aaaaaa", 0, "", 0u, "cannot find a empty substring in a string"); + mu_assert_strstr_offset("bbaaaaa", 12, "aaa", 0u, "cannot find a substring in a string when offset exceeds string length"); + mu_end; +} + +bool test_naxsi_strnchr(void) { + mu_assert_strnchr("test this strnchr @ function", '@', 18u, "@ is in string"); + mu_assert_strnchr("test this strnchr @ function", '~', 0, "~ is NOT in string"); + mu_assert_strnchr("", 'A', 0, "return NULL when string is empty"); + mu_assert_strnchr(" aaaaaBBBBccc", 'A', 0, "A is NOT in string because is case sensitive"); + mu_end; +} + +bool test_naxsi_is_invalid_utf8(void) { + mu_assert_utf8("aaaaaaa", false, "valid ascii"); + mu_assert_utf8("\xc3\xb1", false, "valid 2 octet sequence"); + mu_assert_utf8("\xc3\x28", true, "invalid 2 octet sequence"); + mu_assert_utf8("\xa0\xa1", true, "invalid sequence identifier"); + mu_assert_utf8("\xe2\x82\xa1", false, "valid 3 octet sequence"); + mu_assert_utf8("\xe2\x28\xa1", true, "invalid 3 octet sequence (in 2nd octet)"); + mu_assert_utf8("\xe2\x82\x28", true, "invalid 3 octet sequence (in 3rd octet)"); + mu_assert_utf8("\xf0\x90\x8c\xbc", false, "valid 4 octet sequence"); + mu_assert_utf8("\xf0\x28\x8c\xbc", true, "invalid 4 octet sequence (in 2nd octet)"); + mu_assert_utf8("\xf0\x90\x28\xbc", true, "invalid 4 octet sequence (in 3rd octet)"); + mu_assert_utf8("\xf0\x28\x8c\x28", true, "invalid 4 octet sequence (in 4th octet)"); + mu_assert_utf8("\xf8\xa1\xa1\xa1\xa1", true, "valid 5 octet sequence, but not unicode"); + mu_assert_utf8("\xfc\xa1\xa1\xa1\xa1\xa1", true, "valid 6 octet sequence, but not unicode"); + mu_end; +} + +int all_tests() { + mu_run_test(test_naxsi_escape_nullbytes); + mu_run_test(test_naxsi_strstr_offset); + mu_run_test(test_naxsi_strnchr); + mu_run_test(test_naxsi_is_invalid_utf8); + return tests_passed != tests_run; +} + +mu_main(all_tests) diff --git a/naxsi_nginx_module/config b/naxsi_nginx_module/config new file mode 100644 index 0000000..b3f6664 --- /dev/null +++ b/naxsi_nginx_module/config @@ -0,0 +1,18 @@ +ngx_addon_name=ngx_http_naxsi_module + +ngx_http_naxsi_module_inc_path=" -I $ngx_addon_dir/../libnaxsi/include " +ngx_http_naxsi_module_libs=" -L $ngx_addon_dir/../libnaxsi/build -lnaxsi " + +if test -n "$ngx_module_link"; then + ngx_module_type=HTTP + ngx_module_name="$ngx_addon_name" + ngx_module_incs="$ngx_http_naxsi_module_inc_path" + ngx_module_libs="$ngx_http_naxsi_module_libs" + ngx_module_srcs="$ngx_addon_dir/ngx_http_naxsi_module.c" + . auto/module +else + HTTP_MODULES="$HTTP_MODULES $ngx_addon_name" + HTTP_INCS="$HTTP_INCS $ngx_http_naxsi_module_inc_path" + HTTP_DEPS="$HTTP_DEPS $ngx_http_naxsi_module_libs" + NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_naxsi_module.c" +fi diff --git a/naxsi_nginx_module/ngx_http_naxsi_module.c b/naxsi_nginx_module/ngx_http_naxsi_module.c new file mode 100644 index 0000000..068a578 --- /dev/null +++ b/naxsi_nginx_module/ngx_http_naxsi_module.c @@ -0,0 +1,214 @@ +// SPDX-FileCopyrightText: 2022 wargio +// SPDX-License-Identifier: LGPL-3.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ngx_naxsi_memory(ppool) naxsi_memory(ppool, &nginx_naxsi_free, &nginx_naxsi_malloc, &nginx_naxsi_calloc) + +extern ngx_module_t ngx_http_naxsi_module; + +static ngx_int_t ngx_http_naxsi_post_configuration(ngx_conf_t *cf); +static void *ngx_http_naxsi_create_main_configuration(ngx_conf_t *cf); +static void *ngx_http_naxsi_create_local_configuration(ngx_conf_t *cf); + +static char *ngx_http_naxsi_main_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_naxsi_basic_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_naxsi_denied_url(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_naxsi_ignore_request(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_naxsi_check_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_naxsi_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); + +static ngx_command_t ngx_http_naxsi_commands[] = { + /* MainRule */ + { ngx_string(NAXSI_KEYWORD_MAIN_RULE), + NGX_HTTP_MAIN_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_main_rule, + NGX_HTTP_MAIN_CONF_OFFSET, + 0, + NULL }, + + /* BasicRule */ + { ngx_string(NAXSI_KEYWORD_BASIC_RULE), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_basic_rule, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* DeniedUrl */ + { ngx_string(NAXSI_KEYWORD_DENIED_URL), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_denied_url, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* IgnoreIP */ + { ngx_string(NAXSI_KEYWORD_IGNORE_IP), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_ignore_request, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* IgnoreCIDR */ + { ngx_string(NAXSI_KEYWORD_IGNORE_CIDR), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_ignore_request, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* CheckRule */ + { ngx_string(NAXSI_KEYWORD_CHECK_RULE), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_1MORE, + ngx_http_naxsi_check_rule, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* LearningMode */ + { ngx_string(NAXSI_KEYWORD_LEARNING_FLAG), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, + ngx_http_naxsi_flags, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* SecRulesEnabled */ + { ngx_string(NAXSI_KEYWORD_ENABLED_FLAG), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, + ngx_http_naxsi_flags, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* SecRulesDisabled */ + { ngx_string(NAXSI_KEYWORD_DISABLED_FLAG), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, + ngx_http_naxsi_flags, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* LibInjectionSql */ + { ngx_string(NAXSI_KEYWORD_LIBINJECTION_SQL), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, + ngx_http_naxsi_flags, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + /* LibInjectionXss */ + { ngx_string(NAXSI_KEYWORD_LIBINJECTION_XSS), + NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, + ngx_http_naxsi_flags, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL }, + + ngx_null_command +}; + +static ngx_http_module_t ngx_http_naxsi_module_context = { + NULL, /* preconfiguration */ + ngx_http_naxsi_post_configuration, /* postconfiguration */ + ngx_http_naxsi_create_main_configuration, /* create main configuration */ + NULL, /* init main configuration */ + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + ngx_http_naxsi_create_local_configuration, /* create location configuration */ + NULL /* merge location configuration */ +}; + +ngx_module_t ngx_http_naxsi_module = { + NGX_MODULE_V1, + &ngx_http_naxsi_module_context, /* module context */ + ngx_http_naxsi_commands, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + +static void nginx_naxsi_free(ngx_pool_t *pool, void *ptr) { + ngx_pfree(pool, ptr); +} + +static void *nginx_naxsi_malloc(ngx_pool_t *pool, size_t size) { + return ngx_palloc(pool, size); +} + +static void *nginx_naxsi_calloc(ngx_pool_t *pool, size_t nmemb, size_t size) { + size_t total = nmemb * size; + return ngx_pcalloc(pool, total); +} + +static ngx_int_t ngx_http_naxsi_rewrite_phase_handler(ngx_http_request_t *request) { + return NGX_ERROR; +} + +static ngx_int_t ngx_http_naxsi_post_configuration(ngx_conf_t *cf) { + ngx_http_handler_pt *rewrite; + ngx_http_core_main_conf_t *conf; + + conf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + if (!conf) { + return NGX_ERROR; + } + + /* register rewrite phase handler */ + rewrite = ngx_array_push(&conf->phases[NGX_HTTP_REWRITE_PHASE].handlers); + if (!rewrite) { + return NGX_ERROR; + } + + *rewrite = ngx_http_naxsi_rewrite_phase_handler; + return NGX_OK; +} + +static void *ngx_http_naxsi_create_main_configuration(ngx_conf_t *cf) { + naxsi_mem_t mem = ngx_naxsi_memory(cf->pool); + return naxsi_config_new(&mem, true); +} + +static void *ngx_http_naxsi_create_local_configuration(ngx_conf_t *cf) { + naxsi_mem_t mem = ngx_naxsi_memory(cf->pool); + return naxsi_config_new(&mem, false); +} + +static char *ngx_http_naxsi_main_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} + +static char *ngx_http_naxsi_basic_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} + +static char *ngx_http_naxsi_denied_url(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} + +static char *ngx_http_naxsi_ignore_request(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} + +static char *ngx_http_naxsi_check_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} + +static char *ngx_http_naxsi_flags(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + return NGX_CONF_ERROR; +} diff --git a/naxsi_src/ext/libinjection/example1.c b/naxsi_src/ext/libinjection/example1.c deleted file mode 100644 index e3e256e..0000000 --- a/naxsi_src/ext/libinjection/example1.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include "libinjection.h" - -int main(int argc, const char* argv[]) -{ - char fingerprint[8]; - const char* input; - size_t slen; - int issqli; - - if (argc < 2) { - fprintf(stderr, "Usage: %s inputstring\n", argv[0]); - return -1; - } - - input = argv[1]; - slen = strlen(input); - - - issqli = libinjection_sqli(input, slen, fingerprint); - if (issqli) { - printf("sqli with fingerprint of '%s'\n", fingerprint); - } else { - printf("not sqli\n"); - } - - - return issqli; -} diff --git a/naxsi_src/ext/libinjection/fptool.c b/naxsi_src/ext/libinjection/fptool.c deleted file mode 100644 index 9a03e4b..0000000 --- a/naxsi_src/ext/libinjection/fptool.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright 2012, 2013 Nick Galbreath - * nickg@client9.com - * BSD License -- see COPYING.txt for details - * - * This is for testing against files in ../data/ *.txt - * Reads from stdin or a list of files, and emits if a line - * is a SQLi attack or not, and does basic statistics - * - */ -#include -#include -#include - - -#include "libinjection.h" -#include "libinjection_sqli.h" - -int main(int argc, const char* argv[]) -{ - size_t slen; - int ok; - int single = 0; - int offset = 1; - - sfilter sf; - if (argc < 2) { - fprintf(stderr, "need more args\n"); - return 1; - } - while (1) { - if (strcmp(argv[offset], "-0") == 0) { - single = 1; - offset += 1; - } else { - break; - } - } - - slen = strlen(argv[offset]); - - if (slen == 0) { - return 1; - } - - /* - * "plain" context.. test string "as-is" - */ - libinjection_sqli_init(&sf, argv[offset], slen, 0); - - if (single) { - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "%s\n", sf.fingerprint); - return 0; - } - - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "plain-asni\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); - - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "plain-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); - - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "single-ansi\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); - - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "single-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); - - libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL); - ok = libinjection_sqli_check_fingerprint(&sf); - fprintf(stdout, "double-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); - - return 0; -} diff --git a/naxsi_src/ext/libinjection/html5_cli.c b/naxsi_src/ext/libinjection/html5_cli.c deleted file mode 100644 index fbc38b8..0000000 --- a/naxsi_src/ext/libinjection/html5_cli.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Copyright 2012, 2013, 2014 Nick Galbreath - * nickg@client9.com - * BSD License -- see COPYING.txt for details - * - * This is for testing against files in ../data/ *.txt - * Reads from stdin or a list of files, and emits if a line - * is a SQLi attack or not, and does basic statistics - * - */ -#include -#include -#include -#include - -#include "libinjection_html5.h" -#include "libinjection_xss.h" -#include "libinjection.h" - -int urlcharmap(char ch); -size_t modp_url_decode(char* dest, const char* s, size_t len); -const char* h5_type_to_string(enum html5_type x); -void print_html5_token(h5_state_t* hs); - -int urlcharmap(char ch) { - switch (ch) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'a': case 'A': return 10; - case 'b': case 'B': return 11; - case 'c': case 'C': return 12; - case 'd': case 'D': return 13; - case 'e': case 'E': return 14; - case 'f': case 'F': return 15; - default: - return 256; - } -} - -size_t modp_url_decode(char* dest, const char* s, size_t len) -{ - const char* deststart = dest; - - size_t i = 0; - int d = 0; - while (i < len) { - switch (s[i]) { - case '+': - *dest++ = ' '; - i += 1; - break; - case '%': - if (i+2 < len) { - d = (urlcharmap(s[i+1]) << 4) | urlcharmap(s[i+2]); - if ( d < 256) { - *dest = (char) d; - dest++; - i += 3; /* loop will increment one time */ - } else { - *dest++ = '%'; - i += 1; - } - } else { - *dest++ = '%'; - i += 1; - } - break; - default: - *dest++ = s[i]; - i += 1; - } - } - *dest = '\0'; - return (size_t)(dest - deststart); /* compute "strlen" of dest */ -} - -const char* h5_type_to_string(enum html5_type x) -{ - switch (x) { - case DATA_TEXT: return "DATA_TEXT"; - case TAG_NAME_OPEN: return "TAG_NAME_OPEN"; - case TAG_NAME_CLOSE: return "TAG_NAME_CLOSE"; - case TAG_NAME_SELFCLOSE: return "TAG_NAME_SELFCLOSE"; - case TAG_DATA: return "TAG_DATA"; - case TAG_CLOSE: return "TAG_CLOSE"; - case ATTR_NAME: return "ATTR_NAME"; - case ATTR_VALUE: return "ATTR_VALUE"; - case TAG_COMMENT: return "TAG_COMMENT"; - case DOCTYPE: return "DOCTYPE"; - default: - assert(0); - } -} - -void print_html5_token(h5_state_t* hs) -{ - char* tmp = (char*) malloc(hs->token_len + 1); - memcpy(tmp, hs->token_start, hs->token_len); - /* TODO.. encode to be printable */ - tmp[hs->token_len] = '\0'; - - printf("%s,%d,%s\n", - h5_type_to_string(hs->token_type), - (int) hs->token_len, - tmp); - - free(tmp); -} - -int main(int argc, const char* argv[]) -{ - size_t slen; - h5_state_t hs; - char* copy; - int offset = 1; - int flag = 0; - int urldecode = 0; - - if (argc < 2) { - fprintf(stderr, "need more args\n"); - return 1; - } - - while (offset < argc) { - if (strcmp(argv[offset], "-u") == 0) { - offset += 1; - urldecode = 1; - - } else if (strcmp(argv[offset], "-f") == 0) { - offset += 1; - flag = atoi(argv[offset]); - offset += 1; - } else { - break; - } - } - - /* ATTENTION: argv is a C-string, null terminated. We copy this - * to it's own location, WITHOUT null byte. This way, valgrind - * can see if we run past the buffer. - */ - - slen = strlen(argv[offset]); - copy = (char* ) malloc(slen); - memcpy(copy, argv[offset], slen); - if (urldecode) { - slen = modp_url_decode(copy, copy, slen); - } - - libinjection_h5_init(&hs, copy, slen, (enum html5_flags) flag); - while (libinjection_h5_next(&hs)) { - print_html5_token(&hs); - } - - if (libinjection_is_xss(copy, slen, flag)) { - printf("is injection!\n"); - } - free(copy); - return 0; -} diff --git a/naxsi_src/ext/libinjection/libinjection.h b/naxsi_src/ext/libinjection/libinjection.h deleted file mode 100644 index 11b14ac..0000000 --- a/naxsi_src/ext/libinjection/libinjection.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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 -# define LIBINJECTION_BEGIN_DECLS extern "C" { -# define LIBINJECTION_END_DECLS } -#else -# define LIBINJECTION_BEGIN_DECLS -# define LIBINJECTION_END_DECLS -#endif - -LIBINJECTION_BEGIN_DECLS - -/* - * Pull in size_t - */ -#include - -/* - * Version info. - * - * This is moved into a function to allow SWIG and other auto-generated - * binding to not be modified during minor release changes. We change - * change the version number in the c source file, and not regenerated - * the binding - * - * See python's normalized version - * http://www.python.org/dev/peps/pep-0386/#normalizedversion - */ -const char* libinjection_version(void); - -/** - * Simple API for SQLi detection - returns a SQLi fingerprint or NULL - * is benign input - * - * \param[in] s input string, may contain nulls, does not need to be null-terminated - * \param[in] slen input string length - * \param[out] fingerprint buffer of 8+ characters. c-string, - * \return 1 if SQLi, 0 if benign. fingerprint will be set or set to empty string. - */ -int libinjection_sqli(const char* s, size_t slen, char fingerprint[]); - -/** ALPHA version of xss detector. - * - * NOT DONE. - * - * \param[in] s input string, may contain nulls, does not need to be null-terminated - * \param[in] slen input string length - * \return 1 if XSS found, 0 if benign - * - */ -int libinjection_xss(const char* s, size_t slen); - -LIBINJECTION_END_DECLS - -#endif /* _LIBINJECTION_H */ diff --git a/naxsi_src/ext/libinjection/libinjection_html5.c b/naxsi_src/ext/libinjection/libinjection_html5.c deleted file mode 100644 index 973bb4d..0000000 --- a/naxsi_src/ext/libinjection/libinjection_html5.c +++ /dev/null @@ -1,847 +0,0 @@ -#include "libinjection_html5.h" - -#include -#include - -#ifdef DEBUG -#include -#define TRACE() printf("%s:%d\n", __FUNCTION__, __LINE__) -#else -#define TRACE() -#endif - - -#define CHAR_EOF -1 -#define CHAR_NULL 0 -#define CHAR_BANG 33 -#define CHAR_DOUBLE 34 -#define CHAR_PERCENT 37 -#define CHAR_SINGLE 39 -#define CHAR_DASH 45 -#define CHAR_SLASH 47 -#define CHAR_LT 60 -#define CHAR_EQUALS 61 -#define CHAR_GT 62 -#define CHAR_QUESTION 63 -#define CHAR_RIGHTB 93 -#define CHAR_TICK 96 - -/* prototypes */ - -static int h5_skip_white(h5_state_t* hs); -static int h5_is_white(char c); -static int h5_state_eof(h5_state_t* hs); -static int h5_state_data(h5_state_t* hs); -static int h5_state_tag_open(h5_state_t* hs); -static int h5_state_tag_name(h5_state_t* hs); -static int h5_state_tag_name_close(h5_state_t* hs); -static int h5_state_end_tag_open(h5_state_t* hs); -static int h5_state_self_closing_start_tag(h5_state_t* hs); -static int h5_state_attribute_name(h5_state_t* hs); -static int h5_state_after_attribute_name(h5_state_t* hs); -static int h5_state_before_attribute_name(h5_state_t* hs); -static int h5_state_before_attribute_value(h5_state_t* hs); -static int h5_state_attribute_value_double_quote(h5_state_t* hs); -static int h5_state_attribute_value_single_quote(h5_state_t* hs); -static int h5_state_attribute_value_back_quote(h5_state_t* hs); -static int h5_state_attribute_value_no_quote(h5_state_t* hs); -static int h5_state_after_attribute_value_quoted_state(h5_state_t* hs); -static int h5_state_comment(h5_state_t* hs); -static int h5_state_cdata(h5_state_t* hs); - - -/* 12.2.4.44 */ -static int h5_state_bogus_comment(h5_state_t* hs); -static int h5_state_bogus_comment2(h5_state_t* hs); - -/* 12.2.4.45 */ -static int h5_state_markup_declaration_open(h5_state_t* hs); - -/* 8.2.4.52 */ -static int h5_state_doctype(h5_state_t* hs); - -/** - * public function - */ -void libinjection_h5_init(h5_state_t* hs, const char* s, size_t len, enum html5_flags flags) -{ - memset(hs, 0, sizeof(h5_state_t)); - hs->s = s; - hs->len = len; - - switch (flags) { - case DATA_STATE: - hs->state = h5_state_data; - break; - case VALUE_NO_QUOTE: - hs->state = h5_state_before_attribute_name; - break; - case VALUE_SINGLE_QUOTE: - hs->state = h5_state_attribute_value_single_quote; - break; - case VALUE_DOUBLE_QUOTE: - hs->state = h5_state_attribute_value_double_quote; - break; - case VALUE_BACK_QUOTE: - hs->state = h5_state_attribute_value_back_quote; - break; - } -} - -/** - * public function - */ -int libinjection_h5_next(h5_state_t* hs) -{ - assert(hs->state != NULL); - return (*hs->state)(hs); -} - -/** - * Everything below here is private - * - */ - - -static int h5_is_white(char ch) -{ - /* - * \t = htab = 0x09 - * \n = newline = 0x0A - * \v = vtab = 0x0B - * \f = form feed = 0x0C - * \r = cr = 0x0D - */ - return strchr(" \t\n\v\f\r", ch) != NULL; -} - -static int h5_skip_white(h5_state_t* hs) -{ - char ch; - while (hs->pos < hs->len) { - ch = hs->s[hs->pos]; - switch (ch) { - case 0x00: /* IE only */ - case 0x20: - case 0x09: - case 0x0A: - case 0x0B: /* IE only */ - case 0x0C: - case 0x0D: /* IE only */ - hs->pos += 1; - break; - default: - return ch; - } - } - return CHAR_EOF; -} - -static int h5_state_eof(h5_state_t* hs) -{ - /* eliminate unused function argument warning */ - (void)hs; - return 0; -} - -static int h5_state_data(h5_state_t* hs) -{ - const char* idx; - - TRACE(); - assert(hs->len >= hs->pos); - idx = (const char*) memchr(hs->s + hs->pos, CHAR_LT, hs->len - hs->pos); - if (idx == NULL) { - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = DATA_TEXT; - hs->state = h5_state_eof; - if (hs->token_len == 0) { - return 0; - } - } else { - hs->token_start = hs->s + hs->pos; - hs->token_type = DATA_TEXT; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx - hs->s) + 1; - hs->state = h5_state_tag_open; - if (hs->token_len == 0) { - return h5_state_tag_open(hs); - } - } - return 1; -} - -/** - * 12 2.4.8 - */ -static int h5_state_tag_open(h5_state_t* hs) -{ - char ch; - - TRACE(); - ch = hs->s[hs->pos]; - if (ch == CHAR_BANG) { - hs->pos += 1; - return h5_state_markup_declaration_open(hs); - } else if (ch == CHAR_SLASH) { - hs->pos += 1; - hs->is_close = 1; - return h5_state_end_tag_open(hs); - } else if (ch == CHAR_QUESTION) { - hs->pos += 1; - return h5_state_bogus_comment(hs); - } else if (ch == CHAR_PERCENT) { - /* this is not in spec.. alternative comment format used - by IE <= 9 and Safari < 4.0.3 */ - hs->pos += 1; - return h5_state_bogus_comment2(hs); - } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { - return h5_state_tag_name(hs); - } else if (ch == CHAR_NULL) { - /* IE-ism NULL characters are ignored */ - return h5_state_tag_name(hs); - } else { - /* user input mistake in configuring state */ - if (hs->pos == 0) { - return h5_state_data(hs); - } - hs->token_start = hs->s + hs->pos - 1; - hs->token_len = 1; - hs->token_type = DATA_TEXT; - hs->state = h5_state_data; - return 1; - } -} -/** - * 12.2.4.9 - */ -static int h5_state_end_tag_open(h5_state_t* hs) -{ - char ch; - - TRACE(); - - if (hs->pos >= hs->len) { - return 0; - } - ch = hs->s[hs->pos]; - if (ch == CHAR_GT) { - return h5_state_data(hs); - } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { - return h5_state_tag_name(hs); - } - - hs->is_close = 0; - return h5_state_bogus_comment(hs); -} -/* - * - */ -static int h5_state_tag_name_close(h5_state_t* hs) -{ - TRACE(); - hs->is_close = 0; - hs->token_start = hs->s + hs->pos; - hs->token_len = 1; - hs->token_type = TAG_NAME_CLOSE; - hs->pos += 1; - if (hs->pos < hs->len) { - hs->state = h5_state_data; - } else { - hs->state = h5_state_eof; - } - - return 1; -} - -/** - * 12.2.4.10 - */ -static int h5_state_tag_name(h5_state_t* hs) -{ - char ch; - size_t pos; - - TRACE(); - pos = hs->pos; - while (pos < hs->len) { - ch = hs->s[pos]; - if (ch == 0) { - /* special non-standard case */ - /* allow nulls in tag name */ - /* some old browsers apparently allow and ignore them */ - pos += 1; - } else if (h5_is_white(ch)) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = TAG_NAME_OPEN; - hs->pos = pos + 1; - hs->state = h5_state_before_attribute_name; - return 1; - } else if (ch == CHAR_SLASH) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = TAG_NAME_OPEN; - hs->pos = pos + 1; - hs->state = h5_state_self_closing_start_tag; - return 1; - } else if (ch == CHAR_GT) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - if (hs->is_close) { - hs->pos = pos + 1; - hs->is_close = 0; - hs->token_type = TAG_CLOSE; - hs->state = h5_state_data; - } else { - hs->pos = pos; - hs->token_type = TAG_NAME_OPEN; - hs->state = h5_state_tag_name_close; - } - return 1; - } else { - pos += 1; - } - } - - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = TAG_NAME_OPEN; - hs->state = h5_state_eof; - return 1; -} - -/** - * 12.2.4.34 - */ -static int h5_state_before_attribute_name(h5_state_t* hs) -{ - int ch; - - TRACE(); - ch = h5_skip_white(hs); - switch (ch) { - case CHAR_EOF: { - return 0; - } - case CHAR_SLASH: { - hs->pos += 1; - return h5_state_self_closing_start_tag(hs); - } - case CHAR_GT: { - hs->state = h5_state_data; - hs->token_start = hs->s + hs->pos; - hs->token_len = 1; - hs->token_type = TAG_NAME_CLOSE; - hs->pos += 1; - return 1; - } - default: { - return h5_state_attribute_name(hs); - } - } -} - -static int h5_state_attribute_name(h5_state_t* hs) -{ - char ch; - size_t pos; - - TRACE(); - pos = hs->pos + 1; - while (pos < hs->len) { - ch = hs->s[pos]; - if (h5_is_white(ch)) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = ATTR_NAME; - hs->state = h5_state_after_attribute_name; - hs->pos = pos + 1; - return 1; - } else if (ch == CHAR_SLASH) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = ATTR_NAME; - hs->state = h5_state_self_closing_start_tag; - hs->pos = pos + 1; - return 1; - } else if (ch == CHAR_EQUALS) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = ATTR_NAME; - hs->state = h5_state_before_attribute_value; - hs->pos = pos + 1; - return 1; - } else if (ch == CHAR_GT) { - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->token_type = ATTR_NAME; - hs->state = h5_state_tag_name_close; - hs->pos = pos; - return 1; - } else { - pos += 1; - } - } - /* EOF */ - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = ATTR_NAME; - hs->state = h5_state_eof; - hs->pos = hs->len; - return 1; -} - -/** - * 12.2.4.36 - */ -static int h5_state_after_attribute_name(h5_state_t* hs) -{ - int c; - - TRACE(); - c = h5_skip_white(hs); - switch (c) { - case CHAR_EOF: { - return 0; - } - case CHAR_SLASH: { - hs->pos += 1; - return h5_state_self_closing_start_tag(hs); - } - case CHAR_EQUALS: { - hs->pos += 1; - return h5_state_before_attribute_value(hs); - } - case CHAR_GT: { - return h5_state_tag_name_close(hs); - } - default: { - return h5_state_attribute_name(hs); - } - } -} - -/** - * 12.2.4.37 - */ -static int h5_state_before_attribute_value(h5_state_t* hs) -{ - int c; - TRACE(); - - c = h5_skip_white(hs); - - if (c == CHAR_EOF) { - hs->state = h5_state_eof; - return 0; - } - - if (c == CHAR_DOUBLE) { - return h5_state_attribute_value_double_quote(hs); - } else if (c == CHAR_SINGLE) { - return h5_state_attribute_value_single_quote(hs); - } else if (c == CHAR_TICK) { - /* NON STANDARD IE */ - return h5_state_attribute_value_back_quote(hs); - } else { - return h5_state_attribute_value_no_quote(hs); - } -} - - -static int h5_state_attribute_value_quote(h5_state_t* hs, char qchar) -{ - const char* idx; - - TRACE(); - - /* skip initial quote in normal case. - * dont do this is pos == 0 since it means we have started - * in a non-data state. given an input of '>pos > 0) { - hs->pos += 1; - } - - - idx = (const char*) memchr(hs->s + hs->pos, qchar, hs->len - hs->pos); - if (idx == NULL) { - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = ATTR_VALUE; - hs->state = h5_state_eof; - } else { - hs->token_start = hs->s + hs->pos; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->token_type = ATTR_VALUE; - hs->state = h5_state_after_attribute_value_quoted_state; - hs->pos += hs->token_len + 1; - } - return 1; -} - -static -int h5_state_attribute_value_double_quote(h5_state_t* hs) -{ - TRACE(); - return h5_state_attribute_value_quote(hs, CHAR_DOUBLE); -} - -static -int h5_state_attribute_value_single_quote(h5_state_t* hs) -{ - TRACE(); - return h5_state_attribute_value_quote(hs, CHAR_SINGLE); -} - -static -int h5_state_attribute_value_back_quote(h5_state_t* hs) -{ - TRACE(); - return h5_state_attribute_value_quote(hs, CHAR_TICK); -} - -static int h5_state_attribute_value_no_quote(h5_state_t* hs) -{ - char ch; - size_t pos; - - TRACE(); - pos = hs->pos; - while (pos < hs->len) { - ch = hs->s[pos]; - if (h5_is_white(ch)) { - hs->token_type = ATTR_VALUE; - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->pos = pos + 1; - hs->state = h5_state_before_attribute_name; - return 1; - } else if (ch == CHAR_GT) { - hs->token_type = ATTR_VALUE; - hs->token_start = hs->s + hs->pos; - hs->token_len = pos - hs->pos; - hs->pos = pos; - hs->state = h5_state_tag_name_close; - return 1; - } - pos += 1; - } - TRACE(); - /* EOF */ - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = ATTR_VALUE; - return 1; -} - -/** - * 12.2.4.41 - */ -static int h5_state_after_attribute_value_quoted_state(h5_state_t* hs) -{ - char ch; - - TRACE(); - if (hs->pos >= hs->len) { - return 0; - } - ch = hs->s[hs->pos]; - if (h5_is_white(ch)) { - hs->pos += 1; - return h5_state_before_attribute_name(hs); - } else if (ch == CHAR_SLASH) { - hs->pos += 1; - return h5_state_self_closing_start_tag(hs); - } else if (ch == CHAR_GT) { - hs->token_start = hs->s + hs->pos; - hs->token_len = 1; - hs->token_type = TAG_NAME_CLOSE; - hs->pos += 1; - hs->state = h5_state_data; - return 1; - } else { - return h5_state_before_attribute_name(hs); - } -} - -/** - * 12.2.4.43 - */ -static int h5_state_self_closing_start_tag(h5_state_t* hs) -{ - char ch; - - TRACE(); - if (hs->pos >= hs->len) { - return 0; - } - ch = hs->s[hs->pos]; - if (ch == CHAR_GT) { - assert(hs->pos > 0); - hs->token_start = hs->s + hs->pos -1; - hs->token_len = 2; - hs->token_type = TAG_NAME_SELFCLOSE; - hs->state = h5_state_data; - hs->pos += 1; - return 1; - } else { - return h5_state_before_attribute_name(hs); - } -} - -/** - * 12.2.4.44 - */ -static int h5_state_bogus_comment(h5_state_t* hs) -{ - const char* idx; - - TRACE(); - idx = (const char*) memchr(hs->s + hs->pos, CHAR_GT, hs->len - hs->pos); - if (idx == NULL) { - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->pos = hs->len; - hs->state = h5_state_eof; - } else { - hs->token_start = hs->s + hs->pos; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx - hs->s) + 1; - hs->state = h5_state_data; - } - - hs->token_type = TAG_COMMENT; - return 1; -} - -/** - * 12.2.4.44 ALT - */ -static int h5_state_bogus_comment2(h5_state_t* hs) -{ - const char* idx; - size_t pos; - - TRACE(); - pos = hs->pos; - while (1) { - idx = (const char*) memchr(hs->s + pos, CHAR_PERCENT, hs->len - pos); - if (idx == NULL || (idx + 1 >= hs->s + hs->len)) { - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->pos = hs->len; - hs->token_type = TAG_COMMENT; - hs->state = h5_state_eof; - return 1; - } - - if (*(idx +1) != CHAR_GT) { - pos = (size_t)(idx - hs->s) + 1; - continue; - } - - /* ends in %> */ - hs->token_start = hs->s + hs->pos; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx - hs->s) + 2; - hs->state = h5_state_data; - hs->token_type = TAG_COMMENT; - return 1; - } -} - -/** - * 8.2.4.45 - */ -static int h5_state_markup_declaration_open(h5_state_t* hs) -{ - size_t remaining; - - TRACE(); - remaining = hs->len - hs->pos; - if (remaining >= 7 && - /* case insensitive */ - (hs->s[hs->pos + 0] == 'D' || hs->s[hs->pos + 0] == 'd') && - (hs->s[hs->pos + 1] == 'O' || hs->s[hs->pos + 1] == 'o') && - (hs->s[hs->pos + 2] == 'C' || hs->s[hs->pos + 2] == 'c') && - (hs->s[hs->pos + 3] == 'T' || hs->s[hs->pos + 3] == 't') && - (hs->s[hs->pos + 4] == 'Y' || hs->s[hs->pos + 4] == 'y') && - (hs->s[hs->pos + 5] == 'P' || hs->s[hs->pos + 5] == 'p') && - (hs->s[hs->pos + 6] == 'E' || hs->s[hs->pos + 6] == 'e') - ) { - return h5_state_doctype(hs); - } else if (remaining >= 7 && - /* upper case required */ - hs->s[hs->pos + 0] == '[' && - hs->s[hs->pos + 1] == 'C' && - hs->s[hs->pos + 2] == 'D' && - hs->s[hs->pos + 3] == 'A' && - hs->s[hs->pos + 4] == 'T' && - hs->s[hs->pos + 5] == 'A' && - hs->s[hs->pos + 6] == '[' - ) { - hs->pos += 7; - return h5_state_cdata(hs); - } else if (remaining >= 2 && - hs->s[hs->pos + 0] == '-' && - hs->s[hs->pos + 1] == '-') { - hs->pos += 2; - return h5_state_comment(hs); - } - - return h5_state_bogus_comment(hs); -} - -/** - * 12.2.4.48 - * 12.2.4.49 - * 12.2.4.50 - * 12.2.4.51 - * state machine spec is confusing since it can only look - * at one character at a time but simply it's comments end by: - * 1) EOF - * 2) ending in --> - * 3) ending in -!> - */ -static int h5_state_comment(h5_state_t* hs) -{ - char ch; - const char* idx; - size_t pos; - size_t offset; - const char* end = hs->s + hs->len; - - TRACE(); - pos = hs->pos; - while (1) { - - idx = (const char*) memchr(hs->s + pos, CHAR_DASH, hs->len - pos); - - /* did not find anything or has less than 3 chars left */ - if (idx == NULL || idx > hs->s + hs->len - 3) { - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = TAG_COMMENT; - return 1; - } - offset = 1; - - /* skip all nulls */ - while (idx + offset < end && *(idx + offset) == 0) { - offset += 1; - } - if (idx + offset == end) { - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = TAG_COMMENT; - return 1; - } - - ch = *(idx + offset); - if (ch != CHAR_DASH && ch != CHAR_BANG) { - pos = (size_t)(idx - hs->s) + 1; - continue; - } - - /* need to test */ -#if 0 - /* skip all nulls */ - while (idx + offset < end && *(idx + offset) == 0) { - offset += 1; - } - if (idx + offset == end) { - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = TAG_COMMENT; - return 1; - } -#endif - - offset += 1; - if (idx + offset == end) { - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = TAG_COMMENT; - return 1; - } - - - ch = *(idx + offset); - if (ch != CHAR_GT) { - pos = (size_t)(idx - hs->s) + 1; - continue; - } - offset += 1; - - /* ends in --> or -!> */ - hs->token_start = hs->s + hs->pos; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx + offset - hs->s); - hs->state = h5_state_data; - hs->token_type = TAG_COMMENT; - return 1; - } -} - -static int h5_state_cdata(h5_state_t* hs) -{ - const char* idx; - size_t pos; - - TRACE(); - pos = hs->pos; - while (1) { - idx = (const char*) memchr(hs->s + pos, CHAR_RIGHTB, hs->len - pos); - - /* did not find anything or has less than 3 chars left */ - if (idx == NULL || idx > hs->s + hs->len - 3) { - hs->state = h5_state_eof; - hs->token_start = hs->s + hs->pos; - hs->token_len = hs->len - hs->pos; - hs->token_type = DATA_TEXT; - return 1; - } else if ( *(idx+1) == CHAR_RIGHTB && *(idx+2) == CHAR_GT) { - hs->state = h5_state_data; - hs->token_start = hs->s + hs->pos; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx - hs->s) + 3; - hs->token_type = DATA_TEXT; - return 1; - } else { - pos = (size_t)(idx - hs->s) + 1; - } - } -} - -/** - * 8.2.4.52 - * http://www.w3.org/html/wg/drafts/html/master/syntax.html#doctype-state - */ -static int h5_state_doctype(h5_state_t* hs) -{ - const char* idx; - - TRACE(); - hs->token_start = hs->s + hs->pos; - hs->token_type = DOCTYPE; - - idx = (const char*) memchr(hs->s + hs->pos, CHAR_GT, hs->len - hs->pos); - if (idx == NULL) { - hs->state = h5_state_eof; - hs->token_len = hs->len - hs->pos; - } else { - hs->state = h5_state_data; - hs->token_len = (size_t)(idx - hs->s) - hs->pos; - hs->pos = (size_t)(idx - hs->s) + 1; - } - return 1; -} diff --git a/naxsi_src/ext/libinjection/libinjection_html5.h b/naxsi_src/ext/libinjection/libinjection_html5.h deleted file mode 100644 index 29a1459..0000000 --- a/naxsi_src/ext/libinjection/libinjection_html5.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef LIBINJECTION_HTML5 -#define LIBINJECTION_HTML5 - -#ifdef __cplusplus -extern "C" { -#endif - -/* pull in size_t */ - -#include - -enum html5_type { - DATA_TEXT - , TAG_NAME_OPEN - , TAG_NAME_CLOSE - , TAG_NAME_SELFCLOSE - , TAG_DATA - , TAG_CLOSE - , ATTR_NAME - , ATTR_VALUE - , TAG_COMMENT - , DOCTYPE -}; - -enum html5_flags { - DATA_STATE - , VALUE_NO_QUOTE - , VALUE_SINGLE_QUOTE - , VALUE_DOUBLE_QUOTE - , VALUE_BACK_QUOTE -}; - -struct h5_state; -typedef int (*ptr_html5_state)(struct h5_state*); - -typedef struct h5_state { - const char* s; - size_t len; - size_t pos; - int is_close; - ptr_html5_state state; - const char* token_start; - size_t token_len; - enum html5_type token_type; -} h5_state_t; - - -void libinjection_h5_init(h5_state_t* hs, const char* s, size_t len, enum html5_flags); -int libinjection_h5_next(h5_state_t* hs); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/naxsi_src/ext/libinjection/libinjection_sqli.c b/naxsi_src/ext/libinjection/libinjection_sqli.c deleted file mode 100644 index 83ff80c..0000000 --- a/naxsi_src/ext/libinjection/libinjection_sqli.c +++ /dev/null @@ -1,2298 +0,0 @@ -/** - * 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 - -#include "libinjection.h" -#include "libinjection_sqli.h" -#include "libinjection_sqli_data.h" - -#define LIBINJECTION_VERSION "3.9.1" - -#define LIBINJECTION_SQLI_TOKEN_SIZE sizeof(((stoken_t*)(0))->val) -#define LIBINJECTION_SQLI_MAX_TOKENS 5 - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define CHAR_NULL '\0' -#define CHAR_SINGLE '\'' -#define CHAR_DOUBLE '"' -#define CHAR_TICK '`' - -/* 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 - -/* - * 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_LEFTBRACE = (int)'{' - , TYPE_RIGHTBRACE = (int)'}' - , TYPE_DOT = (int)'.' - , 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) { - /* safe since cur < len - 1 always */ - if (cur[0] == c0 && cur[1] == c1) { - return cur; - } - cur += 1; - } - - return NULL; -} - -/** - * memmem might not exist on some systems - */ -static const char * -my_memmem(const char* haystack, size_t hlen, const char* needle, size_t nlen) -{ - const char* cur; - const char* last; - assert(haystack); - assert(needle); - assert(nlen > 1); - 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; - } - } - - 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) -{ - /* done to elimiate unused warning */ - (void)len; - st->type = (char) stype; - st->pos = pos; - st->len = 1; - 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 = last; - 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, 3) == 0; - default: - return FALSE; - } -} - -/* Parsers - * - * - */ - -static size_t parse_white(struct libinjection_sqli_state * sf) -{ - return sf->pos + 1; -} - -static size_t parse_operator1(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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, (size_t)(endpos - cs) - pos, cs + pos); - return (size_t)((endpos - cs) + 1); - } -} - -/** In Ansi mode, hash is an operator - * In MYSQL mode, it's a EOL comment like '--' - */ -static size_t parse_hash(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * sf) -{ - const char* ptr; - 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; - if (pos1 == slen || cs[pos1] != '*') { - return parse_operator1(sf); - } - - /* - * skip over initial '/x' - */ - ptr = memchr2(cur + 2, slen - (pos + 2), '*', '/'); - - /* - * (ptr == NULL) causes false positive in cppcheck 1.61 - * casting to type seems to fix it - */ - if (ptr == (const char*) NULL) { - /* till end of line */ - clen = slen - pos; - } else { - clen = (size_t)(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, (size_t)(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(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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 delimiter - * - * 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, - (size_t)((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, - (size_t)((cs + len) - (qpos + 2))); - continue; - } else { - /* hey it's a normal string */ - st_assign(st, TYPE_STRING, pos + offset, - (size_t)(qpos - (cs + pos + offset)), cs + pos + offset); - st->str_close = delim; - return (size_t)(qpos - cs + 1); - } - } -} - -/** - * Used when first char is a ' or " - */ -static size_t parse_string(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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); -} - -static size_t parse_ustring(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * sf, size_t 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]; - - /* the ch > 127 is un-needed since - * we assume char is signed - */ - 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, (size_t)(strend - cs) - pos - 3, cs + pos + 3); - sf->current->str_open = 'q'; - sf->current->str_close = 'q'; - return (size_t)(strend - cs + 2); - } -} - -/* - * Oracle's q string - */ -static size_t parse_qstring(struct libinjection_sqli_state * sf) -{ - return parse_qstring_core(sf, 0); -} - -/* - * mysql's N'STRING' or - * ... Oracle's nq string - */ -static size_t parse_nqstring(struct libinjection_sqli_state * 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(struct libinjection_sqli_state *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(struct libinjection_sqli_state *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; -} - -/** - * This handles MS SQLSERVER bracket words - * http://stackoverflow.com/questions/3551284/sql-serverwhat-do-brackets-mean-around-column-name - * - */ -static size_t parse_bword(struct libinjection_sqli_state * sf) -{ - const char *cs = sf->s; - size_t pos = sf->pos; - const char* endptr = (const char*) memchr(cs + pos, ']', sf->slen - pos); - if (endptr == NULL) { - st_assign(sf->current, TYPE_BAREWORD, pos, sf->slen - pos, cs + pos); - return sf->slen; - } else { - st_assign(sf->current, TYPE_BAREWORD, pos, (size_t)(endptr - cs) - pos + 1, cs + pos); - return (size_t)((endptr - cs) + 1); - } -} - -static size_t parse_word(struct libinjection_sqli_state * 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\"\240\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(struct libinjection_sqli_state* sf) -{ - size_t pos = parse_string_core(sf->s, sf->slen, sf->pos, sf->current, CHAR_TICK, 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_BAREWORD; - } - return pos; -} - -static size_t parse_var(struct libinjection_sqli_state * 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(struct libinjection_sqli_state *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, - (size_t)(strend - (cs + pos + 2)), cs + pos + 2); - sf->current->str_open = '$'; - sf->current->str_close = '$'; - return (size_t)(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, - (size_t)(strend - (cs + pos + xlen + 2)), cs+pos+xlen+2); - sf->current->str_open = '$'; - sf->current->str_close = '$'; - return (size_t)((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(struct libinjection_sqli_state * 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; - int have_e = 0; - int have_exp = 0; - - /* 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) { - /* only one character read so far */ - st_assign_char(sf->current, TYPE_DOT, start, 1, '.'); - return pos; - } - } - - if (pos < slen) { - if (cs[pos] == 'E' || cs[pos] == 'e') { - have_e = 1; - pos += 1; - if (pos < slen && (cs[pos] == '+' || cs[pos] == '-')) { - pos += 1; - } - while (pos < slen && ISDIGIT(cs[pos])) { - have_exp = 1; - 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 && (cs[pos] == 'd' || cs[pos] == 'D' || cs[pos] == 'f' || cs[pos] == 'F')) { - if (pos + 1 == slen) { - /* line ends evaluate "... 1.2f$" as '1.2f' */ - pos += 1; - } else if ((char_is_white(cs[pos+1]) || cs[pos+1] == ';')) { - /* - * easy case, evaluate "... 1.2f ... as '1.2f' - */ - pos += 1; - } else if (cs[pos+1] == 'u' || cs[pos+1] == 'U') { - /* - * a bit of a hack but makes '1fUNION' parse as '1f UNION' - */ - pos += 1; - } else { - /* it's like "123FROM" */ - /* parse as "123" only */ - } - } - - if (have_e == 1 && have_exp == 0) { - /* very special form of - * "1234.e" - * "10.10E" - * ".E" - * this is a WORD not a number!! */ - st_assign(sf->current, TYPE_BAREWORD, start, pos - start, cs + start); - } else { - st_assign(sf->current, TYPE_NUMBER, start, pos - start, cs + start); - } - return pos; -} - -/* - * API to return version. This allows us to increment the version - * without having to regenerated the SWIG (or other binding) in minor - * releases. - */ -const char* libinjection_version() -{ - return LIBINJECTION_VERSION; -} - -int libinjection_sqli_tokenize(struct libinjection_sqli_state * 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 char ch = (unsigned char) (s[*pos]); - - /* - * 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(struct libinjection_sqli_state * sf, const char *s, size_t len, int flags) -{ - if (flags == 0) { - flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; - } - - memset(sf, 0, sizeof(struct libinjection_sqli_state)); - 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(struct libinjection_sqli_state * sf, int flags) -{ - void *userdata = sf->userdata; - ptr_lookup_fn lookup = sf->lookup;; - - if (flags == 0) { - flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; - } - libinjection_sqli_init(sf, sf->s, sf->slen, flags); - sf->lookup = lookup; - sf->userdata = userdata; -} - -void libinjection_sqli_callback(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * 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_FUNCTION || - 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_FUNCTION && - 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(struct libinjection_sqli_state * 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 || - sf->current->type == TYPE_SQLTYPE || - 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; - - /* do we have all the max number of tokens? if so do - * some special cases for 5 tokens - */ - if (pos >= LIBINJECTION_SQLI_MAX_TOKENS) { - if ( - ( - sf->tokenvec[0].type == TYPE_NUMBER && - (sf->tokenvec[1].type == TYPE_OPERATOR || sf->tokenvec[1].type == TYPE_COMMA) && - sf->tokenvec[2].type == TYPE_LEFTPARENS && - sf->tokenvec[3].type == TYPE_NUMBER && - sf->tokenvec[4].type == TYPE_RIGHTPARENS - ) || - ( - sf->tokenvec[0].type == TYPE_BAREWORD && - sf->tokenvec[1].type == TYPE_OPERATOR && - sf->tokenvec[2].type == TYPE_LEFTPARENS && - (sf->tokenvec[3].type == TYPE_BAREWORD || sf->tokenvec[3].type == TYPE_NUMBER) && - sf->tokenvec[4].type == TYPE_RIGHTPARENS - ) || - ( - sf->tokenvec[0].type == TYPE_NUMBER && - sf->tokenvec[1].type == TYPE_RIGHTPARENS && - sf->tokenvec[2].type == TYPE_COMMA && - sf->tokenvec[3].type == TYPE_LEFTPARENS && - sf->tokenvec[4].type == TYPE_NUMBER - ) - ) - { - if (pos > LIBINJECTION_SQLI_MAX_TOKENS) { - st_copy(&(sf->tokenvec[1]), &(sf->tokenvec[LIBINJECTION_SQLI_MAX_TOKENS])); - pos = 2; - left = 0; - } else { - pos = 1; - left = 0; - } - } - } - - if (! more || left >= LIBINJECTION_SQLI_MAX_TOKENS) { - left = pos; - break; - } - - /* 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; - continue; - } - - /* 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]) || - sf->tokenvec[left+1].type == TYPE_SQLTYPE)) { - pos -= 1; - sf->stats_folds += 1; - left = 0; - 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_OPERATOR) && ( - cstrcasecmp("LIKE", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 || - cstrcasecmp("NOT LIKE", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0)) { - if (sf->tokenvec[left+1].type == TYPE_LEFTPARENS) { - /* SELECT LIKE(... - * it's a function - */ - sf->tokenvec[left].type = TYPE_FUNCTION; - } - } 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_SQLTYPE || - sf->tokenvec[left+1].type == TYPE_LEFTPARENS || - sf->tokenvec[left+1].type == TYPE_FUNCTION || - 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; - left = 0; - } - } 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; - } else if (sf->tokenvec[left].type == TYPE_LEFTPARENS && - sf->tokenvec[left+1].type == TYPE_LEFTPARENS) { - pos -= 1; - left = 0; - sf->stats_folds += 1; - continue; - } else if (sf->tokenvec[left].type == TYPE_RIGHTPARENS && - sf->tokenvec[left+1].type == TYPE_RIGHTPARENS) { - pos -= 1; - left = 0; - sf->stats_folds += 1; - continue; - } else if (sf->tokenvec[left].type == TYPE_LEFTBRACE && - sf->tokenvec[left+1].type == TYPE_BAREWORD) { - - /* - * MySQL Degenerate case -- - * - * select { ``.``.id }; -- valid !!! - * select { ``.``.``.id }; -- invalid - * select ``.``.id; -- invalid - * select { ``.id }; -- invalid - * - * so it appears {``.``.id} is a magic case - * I suspect this is "current database, current table, field id" - * - * The folding code can't look at more than 3 tokens, and - * I don't want to make two passes. - * - * Since "{ ``" so rare, we are just going to blacklist it. - * - * Highly likely this will need revisiting! - * - * CREDIT @rsalgado 2013-11-25 - */ - if (sf->tokenvec[left+1].len == 0) { - sf->tokenvec[left+1].type = TYPE_EVIL; - return (int)(left+2); - } - /* weird ODBC / MYSQL {foo expr} --> expr - * but for this rule we just strip away the "{ foo" part - */ - left = 0; - pos -= 2; - sf->stats_folds += 2; - continue; - } else if (sf->tokenvec[left+1].type == TYPE_RIGHTBRACE) { - pos -= 1; - left = 0; - sf->stats_folds += 1; - 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; - continue; - } - - /* - * 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; - left = 0; - continue; - } else if (sf->tokenvec[left].type == TYPE_OPERATOR && - sf->tokenvec[left+1].type != TYPE_LEFTPARENS && - sf->tokenvec[left+2].type == TYPE_OPERATOR) { - left = 0; - pos -= 2; - continue; - } else if (sf->tokenvec[left].type == TYPE_LOGIC_OPERATOR && - sf->tokenvec[left+2].type == TYPE_LOGIC_OPERATOR) { - pos -= 2; - left = 0; - 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; - left = 0; - 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; - left = 0; - 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; - left = 0; - 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].type == TYPE_VARIABLE) && - 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 || - sf->tokenvec[left+2].type == TYPE_VARIABLE)) { - pos -= 2; - left = 0; - 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; - left = 0; - 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; - left = 0; - 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)) { - /* - * 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]); - left = 0; - /* pos is >= 3 so this is safe */ - assert(pos >= 3); - pos -= 3; - continue; - } else if (sf->tokenvec[left].type == TYPE_COMMA && - st_is_unary_op(&sf->tokenvec[left+1]) && - sf->tokenvec[left+2].type == TYPE_FUNCTION) { - - /* Separate case from above since you end up with - * 1,-sin(1) --> 1 (1) - * Here, just do - * 1,-sin(1) --> 1,sin(1) - * just remove unary opartor - */ - st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); - pos -= 1; - left = 0; - continue; - } else if ((sf->tokenvec[left].type == TYPE_BAREWORD) && - (sf->tokenvec[left+1].type == TYPE_DOT) && - (sf->tokenvec[left+2].type == TYPE_BAREWORD)) { - /* ignore the '.n' - * typically is this databasename.table - */ - assert(pos >= 3); - pos -= 2; - left = 0; - continue; - } else if ((sf->tokenvec[left].type == TYPE_EXPRESSION) && - (sf->tokenvec[left+1].type == TYPE_DOT) && - (sf->tokenvec[left+2].type == TYPE_BAREWORD)) { - /* select . `foo` --> select `foo` */ - st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]); - pos -= 1; - left = 0; - 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(struct libinjection_sqli_state * sql_state, int flags) -{ - int i; - int tlen = 0; - - libinjection_sqli_reset(sql_state, flags); - - tlen = libinjection_sqli_fold(sql_state); - - /* Check for magic PHP backquote comment - * If: - * * last token is of type "bareword" - * * And is quoted in a backtick - * * And isn't closed - * * And it's empty? - * Then convert it to comment - */ - if (tlen > 2 && - sql_state->tokenvec[tlen-1].type == TYPE_BAREWORD && - sql_state->tokenvec[tlen-1].str_open == CHAR_TICK && - sql_state->tokenvec[tlen-1].len == 0 && - sql_state->tokenvec[tlen-1].str_close == CHAR_NULL) { - sql_state->tokenvec[tlen-1].type = TYPE_COMMENT; - } - - 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; -} - -int libinjection_sqli_check_fingerprint(struct libinjection_sqli_state* sql_state) -{ - return libinjection_sqli_blacklist(sql_state) && - libinjection_sqli_not_whitelist(sql_state); -} - -char libinjection_sqli_lookup_word(struct libinjection_sqli_state *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(struct libinjection_sqli_state* sql_state) -{ - /* - * use minimum of 8 bytes to make sure gcc -fstack-protector - * works correctly - */ - char fp2[8]; - char ch; - size_t i; - size_t len = strlen(sql_state->fingerprint); - int patmatch; - - 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(struct libinjection_sqli_state* 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); - - if (tlen > 1 && sql_state->fingerprint[tlen-1] == TYPE_COMMENT) { - /* - * if ending comment is contains 'sp_password' then it's sqli! - * MS Audit log apparently 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 (my_memmem(sql_state->s, sql_state->slen, - "sp_password", strlen("sp_password"))) { - sql_state->reason = __LINE__; - return TRUE; - } - } - - 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; - } - - /* - * 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; - } - - /** - * 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 (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: - case 5: { - /* nothing right now */ - break; - } /* case 5 */ - } /* end switch */ - - return TRUE; -} - -/** Main API, detects SQLi in an input. - * - * - */ -static int reparse_as_mysql(struct libinjection_sqli_state * sql_state) -{ - return sql_state->stats_comment_ddx || - sql_state->stats_comment_hash; -} - -/* - * This function is mostly use with SWIG - */ -struct libinjection_sqli_token* -libinjection_sqli_get_token(struct libinjection_sqli_state * sql_state, int i) -{ - if (i < 0 || i > (int)LIBINJECTION_SQLI_MAX_TOKENS) { - return NULL; - } - return &(sql_state->tokenvec[i]); -} - -int libinjection_is_sqli(struct libinjection_sqli_state * 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; -} - -int libinjection_sqli(const char* input, size_t slen, char fingerprint[]) -{ - int issqli; - struct libinjection_sqli_state state; - - libinjection_sqli_init(&state, input, slen, 0); - issqli = libinjection_is_sqli(&state); - if (issqli) { - strcpy(fingerprint, state.fingerprint); - } else { - fingerprint[0] = '\0'; - } - return issqli; -} diff --git a/naxsi_src/ext/libinjection/libinjection_sqli.h b/naxsi_src/ext/libinjection/libinjection_sqli.h deleted file mode 100644 index 4f16db8..0000000 --- a/naxsi_src/ext/libinjection/libinjection_sqli.h +++ /dev/null @@ -1,295 +0,0 @@ -/** - * Copyright 2012, 2013 Nick Galbreath - * nickg@client9.com - * BSD License -- see COPYING.txt for details - * - * https://libinjection.client9.com/ - * - */ - -#ifndef _LIBINJECTION_SQLI_H -#define _LIBINJECTION_SQLI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Pull in size_t - */ -#include - -enum sqli_flags { - FLAG_NONE = 0 - , FLAG_QUOTE_NONE = 1 /* 1 << 0 */ - , FLAG_QUOTE_SINGLE = 2 /* 1 << 1 */ - , FLAG_QUOTE_DOUBLE = 4 /* 1 << 2 */ - - , FLAG_SQL_ANSI = 8 /* 1 << 3 */ - , FLAG_SQL_MYSQL = 16 /* 1 << 4 */ -}; - -enum lookup_type { - LOOKUP_WORD = 1 - , LOOKUP_TYPE = 2 - , LOOKUP_OPERATOR = 3 - , LOOKUP_FINGERPRINT = 4 -}; - -struct libinjection_sqli_token { -#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[32]; -}; - -typedef struct libinjection_sqli_token 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); - -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; - -#ifndef SWIG - /* for SWIG.. don't use this.. use functional API instead */ - - /* MAX TOKENS + 1 since we use one extra token - * to determine the type of the previous token - */ - struct libinjection_sqli_token tokenvec[8]; -#endif - - /* - * Pointer to token position in tokenvec, above - */ - struct libinjection_sqli_token *current; - - /* - * fingerprint pattern c-string - * +1 for ending null - * Mimimum of 8 bytes to add gcc's -fstack-protector to work - */ - char fingerprint[8]; - - /* - * 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; - -}; - -typedef struct libinjection_sqli_state sfilter; - -struct libinjection_sqli_token* libinjection_sqli_get_token( - struct libinjection_sqli_state* sqlistate, int i); - -/* - * Version info. - * - * This is moved into a function to allow SWIG and other auto-generated - * binding to not be modified during minor release changes. We change - * change the version number in the c source file, and not regenerated - * the binding - * - * See python's normalized version - * http://www.python.org/dev/peps/pep-0386/#normalizedversion - */ -const char* libinjection_version(void); - -/** - * - */ -void libinjection_sqli_init(struct libinjection_sqli_state* 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 core data structure - * - * \return 1 (true) if SQLi, 0 (false) if benign - */ -int libinjection_is_sqli(struct libinjection_sqli_state* sql_state); - -/* FOR H@CKERS ONLY - * - */ -void libinjection_sqli_callback(struct libinjection_sqli_state* sql_state, - ptr_lookup_fn fn, - void* userdata); - - -/* - * Resets state, but keeps initial string and callbacks - */ -void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state, - int flags); - -/** - * - */ - -/** - * This detects SQLi in a single context, mostly useful for custom - * logic and debugging. - * - * \param sql_state Main data structure - * \param flags flags to adjust parsing - * - * \returns a pointer to sfilter.fingerprint as convenience - * do not free! - * - */ -const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state* 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(struct libinjection_sqli_state* 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(struct libinjection_sqli_state * sql_state); - -/** - * parses and folds input, up to 5 tokens - * - */ -int libinjection_sqli_fold(struct libinjection_sqli_state * 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(struct libinjection_sqli_state * sql_state); - -/* Given a pattern determine if it's a SQLi pattern. - * - * \return TRUE if sqli, false otherwise - */ -int libinjection_sqli_blacklist(struct libinjection_sqli_state* 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(struct libinjection_sqli_state * sql_state); - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBINJECTION_SQLI_H */ diff --git a/naxsi_src/ext/libinjection/libinjection_sqli_data.h b/naxsi_src/ext/libinjection/libinjection_sqli_data.h deleted file mode 100644 index fb570a1..0000000 --- a/naxsi_src/ext/libinjection/libinjection_sqli_data.h +++ /dev/null @@ -1,9349 +0,0 @@ - -#ifndef _LIBINJECTION_SQLI_DATA_H -#define _LIBINJECTION_SQLI_DATA_H - -#include "libinjection.h" -#include "libinjection_sqli.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_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); -static size_t parse_bword(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_bword, /* 91 */ - &parse_backslash, /* 92 */ - &parse_other, /* 93 */ - &parse_operator1, /* 94 */ - &parse_word, /* 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_char, /* 123 */ - &parse_operator2, /* 124 */ - &parse_char, /* 125 */ - &parse_operator1, /* 126 */ - &parse_white, /* 127 */ - &parse_word, /* 128 */ - &parse_word, /* 129 */ - &parse_word, /* 130 */ - &parse_word, /* 131 */ - &parse_word, /* 132 */ - &parse_word, /* 133 */ - &parse_word, /* 134 */ - &parse_word, /* 135 */ - &parse_word, /* 136 */ - &parse_word, /* 137 */ - &parse_word, /* 138 */ - &parse_word, /* 139 */ - &parse_word, /* 140 */ - &parse_word, /* 141 */ - &parse_word, /* 142 */ - &parse_word, /* 143 */ - &parse_word, /* 144 */ - &parse_word, /* 145 */ - &parse_word, /* 146 */ - &parse_word, /* 147 */ - &parse_word, /* 148 */ - &parse_word, /* 149 */ - &parse_word, /* 150 */ - &parse_word, /* 151 */ - &parse_word, /* 152 */ - &parse_word, /* 153 */ - &parse_word, /* 154 */ - &parse_word, /* 155 */ - &parse_word, /* 156 */ - &parse_word, /* 157 */ - &parse_word, /* 158 */ - &parse_word, /* 159 */ - &parse_white, /* 160 */ - &parse_word, /* 161 */ - &parse_word, /* 162 */ - &parse_word, /* 163 */ - &parse_word, /* 164 */ - &parse_word, /* 165 */ - &parse_word, /* 166 */ - &parse_word, /* 167 */ - &parse_word, /* 168 */ - &parse_word, /* 169 */ - &parse_word, /* 170 */ - &parse_word, /* 171 */ - &parse_word, /* 172 */ - &parse_word, /* 173 */ - &parse_word, /* 174 */ - &parse_word, /* 175 */ - &parse_word, /* 176 */ - &parse_word, /* 177 */ - &parse_word, /* 178 */ - &parse_word, /* 179 */ - &parse_word, /* 180 */ - &parse_word, /* 181 */ - &parse_word, /* 182 */ - &parse_word, /* 183 */ - &parse_word, /* 184 */ - &parse_word, /* 185 */ - &parse_word, /* 186 */ - &parse_word, /* 187 */ - &parse_word, /* 188 */ - &parse_word, /* 189 */ - &parse_word, /* 190 */ - &parse_word, /* 191 */ - &parse_word, /* 192 */ - &parse_word, /* 193 */ - &parse_word, /* 194 */ - &parse_word, /* 195 */ - &parse_word, /* 196 */ - &parse_word, /* 197 */ - &parse_word, /* 198 */ - &parse_word, /* 199 */ - &parse_word, /* 200 */ - &parse_word, /* 201 */ - &parse_word, /* 202 */ - &parse_word, /* 203 */ - &parse_word, /* 204 */ - &parse_word, /* 205 */ - &parse_word, /* 206 */ - &parse_word, /* 207 */ - &parse_word, /* 208 */ - &parse_word, /* 209 */ - &parse_word, /* 210 */ - &parse_word, /* 211 */ - &parse_word, /* 212 */ - &parse_word, /* 213 */ - &parse_word, /* 214 */ - &parse_word, /* 215 */ - &parse_word, /* 216 */ - &parse_word, /* 217 */ - &parse_word, /* 218 */ - &parse_word, /* 219 */ - &parse_word, /* 220 */ - &parse_word, /* 221 */ - &parse_word, /* 222 */ - &parse_word, /* 223 */ - &parse_word, /* 224 */ - &parse_word, /* 225 */ - &parse_word, /* 226 */ - &parse_word, /* 227 */ - &parse_word, /* 228 */ - &parse_word, /* 229 */ - &parse_word, /* 230 */ - &parse_word, /* 231 */ - &parse_word, /* 232 */ - &parse_word, /* 233 */ - &parse_word, /* 234 */ - &parse_word, /* 235 */ - &parse_word, /* 236 */ - &parse_word, /* 237 */ - &parse_word, /* 238 */ - &parse_word, /* 239 */ - &parse_word, /* 240 */ - &parse_word, /* 241 */ - &parse_word, /* 242 */ - &parse_word, /* 243 */ - &parse_word, /* 244 */ - &parse_word, /* 245 */ - &parse_word, /* 246 */ - &parse_word, /* 247 */ - &parse_word, /* 248 */ - &parse_word, /* 249 */ - &parse_word, /* 250 */ - &parse_word, /* 251 */ - &parse_word, /* 252 */ - &parse_word, /* 253 */ - &parse_word, /* 254 */ - &parse_word, /* 255 */ -}; - -static const keyword_t sql_keywords[] = { - {"!!", 'o'}, - {"!<", 'o'}, - {"!=", 'o'}, - {"!>", 'o'}, - {"%=", 'o'}, - {"&&", '&'}, - {"&=", 'o'}, - {"*=", 'o'}, - {"+=", 'o'}, - {"-=", 'o'}, - {"/=", 'o'}, - {"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(1", 'F'}, - {"0&(F(F", 'F'}, - {"0&(F(N", 'F'}, - {"0&(F(S", 'F'}, - {"0&(F(V", 'F'}, - {"0&(N)O", 'F'}, - {"0&(N)U", 'F'}, - {"0&(NO(", 'F'}, - {"0&(NOF", 'F'}, - {"0&(NOS", 'F'}, - {"0&(NOV", '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)O", 'F'}, - {"0&(V)U", 'F'}, - {"0&(VO(", 'F'}, - {"0&(VOF", 'F'}, - {"0&(VOS", '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&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()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(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&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(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&SO1S", 'F'}, - {"0&SO1U", 'F'}, - {"0&SO1V", 'F'}, - {"0&SOF(", 'F'}, - {"0&SON(", 'F'}, - {"0&SON1", 'F'}, - {"0&SONF", 'F'}, - {"0&SONU", 'F'}, - {"0&SOS(", 'F'}, - {"0&SOS1", 'F'}, - {"0&SOSF", '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(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&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)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&(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)C", 'F'}, - {"01&1)O", '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(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(1", 'F'}, - {"01&F(E", '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(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)C", 'F'}, - {"01&N)O", '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)C", 'F'}, - {"01&S)O", '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)C", 'F'}, - {"01&V)O", '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(EF(", 'F'}, - {"01(EKF", 'F'}, - {"01(EKN", 'F'}, - {"01(ENK", 'F'}, - {"01(U(E", '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),(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(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)C", '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(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(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)O1U", 'F'}, - {"01)OF(", 'F'}, - {"01)ON&", 'F'}, - {"01)ON)", 'F'}, - {"01)ON;", 'F'}, - {"01)ONB", 'F'}, - {"01)ONC", 'F'}, - {"01)ONK", '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)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(E", 'F'}, - {"01)UE(", 'F'}, - {"01)UE1", 'F'}, - {"01)UEF", 'F'}, - {"01)UEK", 'F'}, - {"01)UEN", 'F'}, - {"01)UES", 'F'}, - {"01)UEV", '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(1", 'F'}, - {"01,F(F", 'F'}, - {"01,F(N", 'F'}, - {"01,F(S", 'F'}, - {"01,F(V", '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;E1K", '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;ENE", 'F'}, - {"01;ENK", 'F'}, - {"01;ENO", 'F'}, - {"01;ENT", 'F'}, - {"01;ES,", 'F'}, - {"01;ES;", 'F'}, - {"01;ESC", 'F'}, - {"01;ESK", 'F'}, - {"01;ESO", 'F'}, - {"01;EST", 'F'}, - {"01;EV,", 'F'}, - {"01;EV;", 'F'}, - {"01;EVC", 'F'}, - {"01;EVK", 'F'}, - {"01;EVO", 'F'}, - {"01;EVT", 'F'}, - {"01;N: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;T1K", '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;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;TSK", '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;TVK", 'F'}, - {"01;TVO", 'F'}, - {"01;TVT", '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(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(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;", '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(1", 'F'}, - {"01BE(F", 'F'}, - {"01BE(N", 'F'}, - {"01BE(S", 'F'}, - {"01BE(V", 'F'}, - {"01BEK(", '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;", '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;", '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,F", '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(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(1", 'F'}, - {"01EF(F", 'F'}, - {"01EF(N", 'F'}, - {"01EF(S", 'F'}, - {"01EF(V", '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(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()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(E(", 'F'}, - {"01F(E1", 'F'}, - {"01F(EF", 'F'}, - {"01F(EK", 'F'}, - {"01F(EN", 'F'}, - {"01F(ES", 'F'}, - {"01F(EV", '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(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);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(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(1)", 'F'}, - {"01N(1O", 'F'}, - {"01N(F(", 'F'}, - {"01N(S)", 'F'}, - {"01N(SO", 'F'}, - {"01N(V)", 'F'}, - {"01N(VO", 'F'}, - {"01N)UE", 'F'}, - {"01N,F(", '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(1", 'F'}, - {"01NF(F", 'F'}, - {"01NF(N", 'F'}, - {"01NF(S", 'F'}, - {"01NF(V", '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(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(S&", 'F'}, - {"01O(S)", 'F'}, - {"01O(S,", 'F'}, - {"01O(SO", 'F'}, - {"01O(V&", 'F'}, - {"01O(V)", 'F'}, - {"01O(V,", 'F'}, - {"01O(VO", '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(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(E", 'F'}, - {"01OS(U", 'F'}, - {"01OS)&", 'F'}, - {"01OS),", 'F'}, - {"01OS);", 'F'}, - {"01OS)B", 'F'}, - {"01OS)C", 'F'}, - {"01OS)E", 'F'}, - {"01OS)K", 'F'}, - {"01OS)O", 'F'}, - {"01OS)U", 'F'}, - {"01OS,(", 'F'}, - {"01OS,F", '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'}, - {"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'}, - {"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(E", 'F'}, - {"01OV(U", 'F'}, - {"01OV)&", 'F'}, - {"01OV),", 'F'}, - {"01OV);", 'F'}, - {"01OV)B", 'F'}, - {"01OV)C", 'F'}, - {"01OV)E", 'F'}, - {"01OV)K", 'F'}, - {"01OV)O", 'F'}, - {"01OV)U", 'F'}, - {"01OV,(", 'F'}, - {"01OV,F", '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'}, - {"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(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(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'}, - {"01U1C", 'F'}, - {"01U1O(", 'F'}, - {"01U1OF", 'F'}, - {"01U1OS", 'F'}, - {"01U1OV", 'F'}, - {"01U;", 'F'}, - {"01U;C", 'F'}, - {"01UC", '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'}, - {"01UENN", '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(1", 'F'}, - {"01UF(F", 'F'}, - {"01UF(N", 'F'}, - {"01UF(S", 'F'}, - {"01UF(V", 'F'}, - {"01UK(E", 'F'}, - {"01UN(1", 'F'}, - {"01UN(F", 'F'}, - {"01UN(S", 'F'}, - {"01UN(V", 'F'}, - {"01UN,(", 'F'}, - {"01UN,F", '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(E", 'F'}, - {"01UON(", 'F'}, - {"01UON1", 'F'}, - {"01UONF", 'F'}, - {"01UONS", 'F'}, - {"01US,(", 'F'}, - {"01US,F", '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,F", 'F'}, - {"01UVC", 'F'}, - {"01UVO(", 'F'}, - {"01UVOF", 'F'}, - {"01UVOS", 'F'}, - {"01VF()", 'F'}, - {"01VF(1", 'F'}, - {"01VF(F", 'F'}, - {"01VF(N", 'F'}, - {"01VF(S", 'F'}, - {"01VF(V", 'F'}, - {"01VO(1", 'F'}, - {"01VO(F", 'F'}, - {"01VO(N", 'F'}, - {"01VO(S", 'F'}, - {"01VO(V", 'F'}, - {"01VOF(", 'F'}, - {"01VOS(", 'F'}, - {"01VOS1", 'F'}, - {"01VOSF", '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(1&(", 'F'}, - {"0E(1&1", 'F'}, - {"0E(1&F", 'F'}, - {"0E(1&N", 'F'}, - {"0E(1&S", 'F'}, - {"0E(1&V", 'F'}, - {"0E(1)&", 'F'}, - {"0E(1),", 'F'}, - {"0E(1)1", 'F'}, - {"0E(1);", 'F'}, - {"0E(1)B", 'F'}, - {"0E(1)C", '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(1O(", 'F'}, - {"0E(1OF", 'F'}, - {"0E(1OS", 'F'}, - {"0E(1OV", 'F'}, - {"0E(1S)", 'F'}, - {"0E(1V)", 'F'}, - {"0E(1VO", '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(E1&", 'F'}, - {"0E(E1)", '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(EN&", 'F'}, - {"0E(EN)", 'F'}, - {"0E(ENO", 'F'}, - {"0E(ES&", 'F'}, - {"0E(ES)", 'F'}, - {"0E(ESO", 'F'}, - {"0E(EV&", 'F'}, - {"0E(EV)", 'F'}, - {"0E(EVO", 'F'}, - {"0E(F()", 'F'}, - {"0E(F(1", 'F'}, - {"0E(F(E", '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&N", 'F'}, - {"0E(N&S", 'F'}, - {"0E(N&V", '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)1", 'F'}, - {"0E(N);", 'F'}, - {"0E(N)B", 'F'}, - {"0E(N)C", '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&1", 'F'}, - {"0E(S&F", 'F'}, - {"0E(S&N", 'F'}, - {"0E(S&S", 'F'}, - {"0E(S&V", 'F'}, - {"0E(S)&", 'F'}, - {"0E(S),", 'F'}, - {"0E(S)1", 'F'}, - {"0E(S);", 'F'}, - {"0E(S)B", 'F'}, - {"0E(S)C", '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&1", 'F'}, - {"0E(V&F", 'F'}, - {"0E(V&N", 'F'}, - {"0E(V&S", 'F'}, - {"0E(V&V", 'F'}, - {"0E(V)&", 'F'}, - {"0E(V),", 'F'}, - {"0E(V)1", 'F'}, - {"0E(V);", 'F'}, - {"0E(V)B", 'F'}, - {"0E(V)C", '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&(1", 'F'}, - {"0E1&(E", 'F'}, - {"0E1&(F", 'F'}, - {"0E1&(N", 'F'}, - {"0E1&(S", 'F'}, - {"0E1&(V", 'F'}, - {"0E1&1)", 'F'}, - {"0E1&1O", 'F'}, - {"0E1&F(", 'F'}, - {"0E1&N)", 'F'}, - {"0E1&NO", 'F'}, - {"0E1&S)", 'F'}, - {"0E1&SO", 'F'}, - {"0E1&V)", 'F'}, - {"0E1&VO", 'F'}, - {"0E1)", 'F'}, - {"0E1)&(", 'F'}, - {"0E1)&1", 'F'}, - {"0E1)&F", 'F'}, - {"0E1)&N", 'F'}, - {"0E1)&S", 'F'}, - {"0E1)&V", 'F'}, - {"0E1);", 'F'}, - {"0E1);(", 'F'}, - {"0E1);C", 'F'}, - {"0E1);E", 'F'}, - {"0E1);T", '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,(1", 'F'}, - {"0E1,(F", 'F'}, - {"0E1,(N", 'F'}, - {"0E1,(S", 'F'}, - {"0E1,(V", 'F'}, - {"0E1,F(", 'F'}, - {"0E1;(E", 'F'}, - {"0E1B(1", 'F'}, - {"0E1B(F", 'F'}, - {"0E1B(N", 'F'}, - {"0E1B(S", 'F'}, - {"0E1B(V", 'F'}, - {"0E1B1)", 'F'}, - {"0E1B1O", 'F'}, - {"0E1BF(", 'F'}, - {"0E1BN)", 'F'}, - {"0E1BNO", 'F'}, - {"0E1BS)", 'F'}, - {"0E1BSO", 'F'}, - {"0E1BV)", 'F'}, - {"0E1BVO", 'F'}, - {"0E1F()", 'F'}, - {"0E1F(1", 'F'}, - {"0E1F(F", 'F'}, - {"0E1F(N", 'F'}, - {"0E1F(S", 'F'}, - {"0E1F(V", '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'}, - {"0E1KNU", 'F'}, - {"0E1KS)", 'F'}, - {"0E1KSK", 'F'}, - {"0E1KSO", 'F'}, - {"0E1KV)", 'F'}, - {"0E1KVK", 'F'}, - {"0E1KVO", 'F'}, - {"0E1N)U", 'F'}, - {"0E1N;", 'F'}, - {"0E1N;C", 'F'}, - {"0E1NC", 'F'}, - {"0E1NKN", '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'}, - {"0E1OS;", 'F'}, - {"0E1OSB", 'F'}, - {"0E1OSF", 'F'}, - {"0E1OSK", 'F'}, - {"0E1OSU", 'F'}, - {"0E1OSV", 'F'}, - {"0E1OV&", 'F'}, - {"0E1OV(", 'F'}, - {"0E1OV)", 'F'}, - {"0E1OV,", 'F'}, - {"0E1OV;", 'F'}, - {"0E1OVB", 'F'}, - {"0E1OVF", 'F'}, - {"0E1OVK", 'F'}, - {"0E1OVO", 'F'}, - {"0E1OVS", 'F'}, - {"0E1OVU", 'F'}, - {"0E1S;", 'F'}, - {"0E1S;C", 'F'}, - {"0E1SC", 'F'}, - {"0E1U(E", 'F'}, - {"0E1UE(", 'F'}, - {"0E1UE1", 'F'}, - {"0E1UEF", 'F'}, - {"0E1UEK", 'F'}, - {"0E1UEN", 'F'}, - {"0E1UES", 'F'}, - {"0E1UEV", 'F'}, - {"0E1V", 'F'}, - {"0E1V;", 'F'}, - {"0E1V;C", 'F'}, - {"0E1VC", 'F'}, - {"0E1VO(", 'F'}, - {"0E1VOF", 'F'}, - {"0E1VOS", 'F'}, - {"0EE(F(", 'F'}, - {"0EEK(F", 'F'}, - {"0EF()&", 'F'}, - {"0EF(),", 'F'}, - {"0EF()1", 'F'}, - {"0EF();", 'F'}, - {"0EF()B", 'F'}, - {"0EF()F", 'F'}, - {"0EF()K", 'F'}, - {"0EF()N", 'F'}, - {"0EF()O", 'F'}, - {"0EF()S", 'F'}, - {"0EF()U", 'F'}, - {"0EF()V", 'F'}, - {"0EF(1&", 'F'}, - {"0EF(1)", 'F'}, - {"0EF(1,", 'F'}, - {"0EF(1O", 'F'}, - {"0EF(E(", 'F'}, - {"0EF(E1", 'F'}, - {"0EF(EF", 'F'}, - {"0EF(EK", 'F'}, - {"0EF(EN", 'F'}, - {"0EF(ES", 'F'}, - {"0EF(EV", 'F'}, - {"0EF(F(", 'F'}, - {"0EF(N&", 'F'}, - {"0EF(N)", 'F'}, - {"0EF(N,", 'F'}, - {"0EF(NO", 'F'}, - {"0EF(O)", 'F'}, - {"0EF(S&", 'F'}, - {"0EF(S)", 'F'}, - {"0EF(S,", 'F'}, - {"0EF(SO", 'F'}, - {"0EF(V&", 'F'}, - {"0EF(V)", 'F'}, - {"0EF(V,", 'F'}, - {"0EF(VO", 'F'}, - {"0EK(1&", '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(N,", 'F'}, - {"0EK(N1", 'F'}, - {"0EK(NF", 'F'}, - {"0EK(NO", 'F'}, - {"0EK(S&", '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(V,", 'F'}, - {"0EK(VF", 'F'}, - {"0EK(VO", 'F'}, - {"0EK(VS", 'F'}, - {"0EK1&(", 'F'}, - {"0EK1&1", 'F'}, - {"0EK1&F", 'F'}, - {"0EK1&N", 'F'}, - {"0EK1&S", 'F'}, - {"0EK1&V", '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;(", 'F'}, - {"0EK1B(", 'F'}, - {"0EK1B1", 'F'}, - {"0EK1BF", 'F'}, - {"0EK1BN", 'F'}, - {"0EK1BS", 'F'}, - {"0EK1BV", 'F'}, - {"0EK1F(", 'F'}, - {"0EK1K(", 'F'}, - {"0EK1K1", 'F'}, - {"0EK1KF", 'F'}, - {"0EK1KN", 'F'}, - {"0EK1KS", 'F'}, - {"0EK1KV", 'F'}, - {"0EK1N", 'F'}, - {"0EK1N)", 'F'}, - {"0EK1N;", 'F'}, - {"0EK1NC", 'F'}, - {"0EK1NF", 'F'}, - {"0EK1NK", 'F'}, - {"0EK1O(", 'F'}, - {"0EK1OF", 'F'}, - {"0EK1OS", 'F'}, - {"0EK1OV", 'F'}, - {"0EK1S", 'F'}, - {"0EK1S;", 'F'}, - {"0EK1SC", 'F'}, - {"0EK1SF", 'F'}, - {"0EK1SK", 'F'}, - {"0EK1U(", 'F'}, - {"0EK1UE", 'F'}, - {"0EK1V", 'F'}, - {"0EK1V;", 'F'}, - {"0EK1VC", 'F'}, - {"0EK1VF", 'F'}, - {"0EK1VK", 'F'}, - {"0EK1VO", 'F'}, - {"0EKE(F", 'F'}, - {"0EKEK(", 'F'}, - {"0EKF()", 'F'}, - {"0EKF(1", 'F'}, - {"0EKF(E", 'F'}, - {"0EKF(F", 'F'}, - {"0EKF(N", 'F'}, - {"0EKF(O", 'F'}, - {"0EKF(S", 'F'}, - {"0EKF(V", 'F'}, - {"0EKN&(", 'F'}, - {"0EKN&1", 'F'}, - {"0EKN&F", 'F'}, - {"0EKN&N", 'F'}, - {"0EKN&S", 'F'}, - {"0EKN&V", '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'}, - {"0EKN1", 'F'}, - {"0EKN1;", 'F'}, - {"0EKN1C", 'F'}, - {"0EKN1F", 'F'}, - {"0EKN1K", 'F'}, - {"0EKN1O", 'F'}, - {"0EKN;(", 'F'}, - {"0EKNB(", 'F'}, - {"0EKNB1", 'F'}, - {"0EKNBF", 'F'}, - {"0EKNBN", 'F'}, - {"0EKNBS", 'F'}, - {"0EKNBV", 'F'}, - {"0EKNF(", 'F'}, - {"0EKNK(", 'F'}, - {"0EKNK1", 'F'}, - {"0EKNKF", 'F'}, - {"0EKNKN", 'F'}, - {"0EKNKS", 'F'}, - {"0EKNKV", 'F'}, - {"0EKNU(", 'F'}, - {"0EKNUE", 'F'}, - {"0EKO(1", 'F'}, - {"0EKO(F", 'F'}, - {"0EKO(N", 'F'}, - {"0EKO(S", 'F'}, - {"0EKO(V", 'F'}, - {"0EKOK(", 'F'}, - {"0EKOKN", 'F'}, - {"0EKS&(", 'F'}, - {"0EKS&1", 'F'}, - {"0EKS&F", 'F'}, - {"0EKS&N", 'F'}, - {"0EKS&S", 'F'}, - {"0EKS&V", 'F'}, - {"0EKS)", 'F'}, - {"0EKS)&", 'F'}, - {"0EKS);", 'F'}, - {"0EKS)C", 'F'}, - {"0EKS)K", 'F'}, - {"0EKS)O", 'F'}, - {"0EKS)U", 'F'}, - {"0EKS,(", 'F'}, - {"0EKS,F", 'F'}, - {"0EKS1", 'F'}, - {"0EKS1;", 'F'}, - {"0EKS1C", 'F'}, - {"0EKS1F", 'F'}, - {"0EKS1K", 'F'}, - {"0EKS1O", 'F'}, - {"0EKS;(", 'F'}, - {"0EKSB(", 'F'}, - {"0EKSB1", 'F'}, - {"0EKSBF", 'F'}, - {"0EKSBN", 'F'}, - {"0EKSBS", 'F'}, - {"0EKSBV", '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'}, - {"0EKSU(", 'F'}, - {"0EKSUE", 'F'}, - {"0EKSV", 'F'}, - {"0EKSV;", 'F'}, - {"0EKSVC", 'F'}, - {"0EKSVF", 'F'}, - {"0EKSVK", 'F'}, - {"0EKSVO", 'F'}, - {"0EKV&(", 'F'}, - {"0EKV&1", 'F'}, - {"0EKV&F", 'F'}, - {"0EKV&N", 'F'}, - {"0EKV&S", 'F'}, - {"0EKV&V", 'F'}, - {"0EKV)", 'F'}, - {"0EKV)&", 'F'}, - {"0EKV);", 'F'}, - {"0EKV)C", 'F'}, - {"0EKV)K", 'F'}, - {"0EKV)O", 'F'}, - {"0EKV)U", 'F'}, - {"0EKV,(", 'F'}, - {"0EKV,F", 'F'}, - {"0EKV;(", 'F'}, - {"0EKVB(", 'F'}, - {"0EKVB1", 'F'}, - {"0EKVBF", 'F'}, - {"0EKVBN", 'F'}, - {"0EKVBS", 'F'}, - {"0EKVBV", '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'}, - {"0EKVU(", 'F'}, - {"0EKVUE", 'F'}, - {"0EN&(1", 'F'}, - {"0EN&(E", 'F'}, - {"0EN&(F", 'F'}, - {"0EN&(N", 'F'}, - {"0EN&(S", 'F'}, - {"0EN&(V", 'F'}, - {"0EN&1)", 'F'}, - {"0EN&1O", 'F'}, - {"0EN&F(", 'F'}, - {"0EN&N)", 'F'}, - {"0EN&NO", 'F'}, - {"0EN&S)", 'F'}, - {"0EN&SO", 'F'}, - {"0EN&V)", 'F'}, - {"0EN&VO", 'F'}, - {"0EN(1O", 'F'}, - {"0EN(F(", 'F'}, - {"0EN(S)", 'F'}, - {"0EN(SO", 'F'}, - {"0EN(V)", 'F'}, - {"0EN(VO", 'F'}, - {"0EN)", 'F'}, - {"0EN)&(", 'F'}, - {"0EN)&1", 'F'}, - {"0EN)&F", 'F'}, - {"0EN)&N", 'F'}, - {"0EN)&S", 'F'}, - {"0EN)&V", 'F'}, - {"0EN);", 'F'}, - {"0EN);(", 'F'}, - {"0EN);C", 'F'}, - {"0EN);E", 'F'}, - {"0EN);T", '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,(1", 'F'}, - {"0EN,(F", 'F'}, - {"0EN,(N", 'F'}, - {"0EN,(S", 'F'}, - {"0EN,(V", 'F'}, - {"0EN,F(", 'F'}, - {"0EN1;", 'F'}, - {"0EN1;C", 'F'}, - {"0EN1C", 'F'}, - {"0EN1O(", 'F'}, - {"0EN1OF", 'F'}, - {"0EN1OS", 'F'}, - {"0EN1OV", 'F'}, - {"0EN;(E", 'F'}, - {"0ENB(1", 'F'}, - {"0ENB(F", 'F'}, - {"0ENB(N", 'F'}, - {"0ENB(S", 'F'}, - {"0ENB(V", 'F'}, - {"0ENB1)", 'F'}, - {"0ENB1O", 'F'}, - {"0ENBF(", 'F'}, - {"0ENBN)", 'F'}, - {"0ENBNO", 'F'}, - {"0ENBS)", 'F'}, - {"0ENBSO", 'F'}, - {"0ENBV)", 'F'}, - {"0ENBVO", 'F'}, - {"0ENF()", 'F'}, - {"0ENF(1", 'F'}, - {"0ENF(F", 'F'}, - {"0ENF(N", 'F'}, - {"0ENF(S", 'F'}, - {"0ENF(V", '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'}, - {"0ENKNU", 'F'}, - {"0ENKS)", 'F'}, - {"0ENKSK", 'F'}, - {"0ENKSO", 'F'}, - {"0ENKV)", 'F'}, - {"0ENKVK", 'F'}, - {"0ENKVO", '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'}, - {"0ENOS;", 'F'}, - {"0ENOSB", 'F'}, - {"0ENOSF", 'F'}, - {"0ENOSK", 'F'}, - {"0ENOSU", 'F'}, - {"0ENOSV", 'F'}, - {"0ENOV&", 'F'}, - {"0ENOV(", 'F'}, - {"0ENOV)", 'F'}, - {"0ENOV,", 'F'}, - {"0ENOV;", 'F'}, - {"0ENOVB", 'F'}, - {"0ENOVF", 'F'}, - {"0ENOVK", 'F'}, - {"0ENOVO", 'F'}, - {"0ENOVS", 'F'}, - {"0ENOVU", 'F'}, - {"0ENU(E", 'F'}, - {"0ENUE(", 'F'}, - {"0ENUE1", 'F'}, - {"0ENUEF", 'F'}, - {"0ENUEK", 'F'}, - {"0ENUEN", 'F'}, - {"0ENUES", 'F'}, - {"0ENUEV", 'F'}, - {"0EOK(E", 'F'}, - {"0EOKNK", 'F'}, - {"0ES&(1", 'F'}, - {"0ES&(E", 'F'}, - {"0ES&(F", 'F'}, - {"0ES&(N", 'F'}, - {"0ES&(S", 'F'}, - {"0ES&(V", 'F'}, - {"0ES&1)", 'F'}, - {"0ES&1O", 'F'}, - {"0ES&F(", 'F'}, - {"0ES&N)", 'F'}, - {"0ES&NO", 'F'}, - {"0ES&S)", 'F'}, - {"0ES&SO", 'F'}, - {"0ES&V)", 'F'}, - {"0ES&VO", 'F'}, - {"0ES)", 'F'}, - {"0ES)&(", 'F'}, - {"0ES)&1", 'F'}, - {"0ES)&F", 'F'}, - {"0ES)&N", 'F'}, - {"0ES)&S", 'F'}, - {"0ES)&V", 'F'}, - {"0ES);", 'F'}, - {"0ES);(", 'F'}, - {"0ES);C", 'F'}, - {"0ES);E", 'F'}, - {"0ES);T", '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,(1", 'F'}, - {"0ES,(F", 'F'}, - {"0ES,(N", 'F'}, - {"0ES,(S", 'F'}, - {"0ES,(V", 'F'}, - {"0ES,F(", 'F'}, - {"0ES1", 'F'}, - {"0ES1;", 'F'}, - {"0ES1;C", 'F'}, - {"0ES1C", 'F'}, - {"0ES1O(", 'F'}, - {"0ES1OF", 'F'}, - {"0ES1OS", 'F'}, - {"0ES1OV", 'F'}, - {"0ES;(E", 'F'}, - {"0ESB(1", 'F'}, - {"0ESB(F", 'F'}, - {"0ESB(N", 'F'}, - {"0ESB(S", 'F'}, - {"0ESB(V", 'F'}, - {"0ESB1)", 'F'}, - {"0ESB1O", 'F'}, - {"0ESBF(", 'F'}, - {"0ESBN)", 'F'}, - {"0ESBNO", 'F'}, - {"0ESBS)", 'F'}, - {"0ESBSO", 'F'}, - {"0ESBV)", 'F'}, - {"0ESBVO", 'F'}, - {"0ESF()", 'F'}, - {"0ESF(1", 'F'}, - {"0ESF(F", 'F'}, - {"0ESF(N", 'F'}, - {"0ESF(S", 'F'}, - {"0ESF(V", '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'}, - {"0ESKNU", 'F'}, - {"0ESKS)", 'F'}, - {"0ESKSK", 'F'}, - {"0ESKSO", 'F'}, - {"0ESKV)", 'F'}, - {"0ESKVK", 'F'}, - {"0ESKVO", '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'}, - {"0ESO1;", 'F'}, - {"0ESO1B", 'F'}, - {"0ESO1F", 'F'}, - {"0ESO1K", 'F'}, - {"0ESO1N", 'F'}, - {"0ESO1S", 'F'}, - {"0ESO1U", 'F'}, - {"0ESO1V", 'F'}, - {"0ESOF(", 'F'}, - {"0ESON&", 'F'}, - {"0ESON(", 'F'}, - {"0ESON)", 'F'}, - {"0ESON,", 'F'}, - {"0ESON1", 'F'}, - {"0ESON;", 'F'}, - {"0ESONB", 'F'}, - {"0ESONF", 'F'}, - {"0ESONK", 'F'}, - {"0ESONU", 'F'}, - {"0ESOS&", 'F'}, - {"0ESOS(", 'F'}, - {"0ESOS)", 'F'}, - {"0ESOS,", 'F'}, - {"0ESOS1", 'F'}, - {"0ESOS;", 'F'}, - {"0ESOSB", 'F'}, - {"0ESOSF", 'F'}, - {"0ESOSK", 'F'}, - {"0ESOSU", 'F'}, - {"0ESOSV", 'F'}, - {"0ESOV&", 'F'}, - {"0ESOV(", 'F'}, - {"0ESOV)", 'F'}, - {"0ESOV,", 'F'}, - {"0ESOV;", 'F'}, - {"0ESOVB", 'F'}, - {"0ESOVF", 'F'}, - {"0ESOVK", 'F'}, - {"0ESOVO", 'F'}, - {"0ESOVS", 'F'}, - {"0ESOVU", 'F'}, - {"0ESU(E", 'F'}, - {"0ESUE(", 'F'}, - {"0ESUE1", 'F'}, - {"0ESUEF", 'F'}, - {"0ESUEK", 'F'}, - {"0ESUEN", 'F'}, - {"0ESUES", 'F'}, - {"0ESUEV", 'F'}, - {"0ESV", 'F'}, - {"0ESV;", 'F'}, - {"0ESV;C", 'F'}, - {"0ESVC", 'F'}, - {"0ESVO(", 'F'}, - {"0ESVOF", 'F'}, - {"0ESVOS", 'F'}, - {"0EV&(1", 'F'}, - {"0EV&(E", 'F'}, - {"0EV&(F", 'F'}, - {"0EV&(N", 'F'}, - {"0EV&(S", 'F'}, - {"0EV&(V", 'F'}, - {"0EV&1)", 'F'}, - {"0EV&1O", 'F'}, - {"0EV&F(", 'F'}, - {"0EV&N)", 'F'}, - {"0EV&NO", 'F'}, - {"0EV&S)", 'F'}, - {"0EV&SO", 'F'}, - {"0EV&V)", 'F'}, - {"0EV&VO", 'F'}, - {"0EV)", 'F'}, - {"0EV)&(", 'F'}, - {"0EV)&1", 'F'}, - {"0EV)&F", 'F'}, - {"0EV)&N", 'F'}, - {"0EV)&S", 'F'}, - {"0EV)&V", 'F'}, - {"0EV);", 'F'}, - {"0EV);(", 'F'}, - {"0EV);C", 'F'}, - {"0EV);E", 'F'}, - {"0EV);T", '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,(1", 'F'}, - {"0EV,(F", 'F'}, - {"0EV,(N", 'F'}, - {"0EV,(S", 'F'}, - {"0EV,(V", 'F'}, - {"0EV,F(", 'F'}, - {"0EV;(E", 'F'}, - {"0EVB(1", 'F'}, - {"0EVB(F", 'F'}, - {"0EVB(N", 'F'}, - {"0EVB(S", 'F'}, - {"0EVB(V", 'F'}, - {"0EVB1)", 'F'}, - {"0EVB1O", 'F'}, - {"0EVBF(", 'F'}, - {"0EVBN)", 'F'}, - {"0EVBNO", 'F'}, - {"0EVBS)", 'F'}, - {"0EVBSO", 'F'}, - {"0EVBV)", 'F'}, - {"0EVBVO", 'F'}, - {"0EVF()", 'F'}, - {"0EVF(1", 'F'}, - {"0EVF(F", 'F'}, - {"0EVF(N", 'F'}, - {"0EVF(S", 'F'}, - {"0EVF(V", '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'}, - {"0EVKNU", 'F'}, - {"0EVKS)", 'F'}, - {"0EVKSK", 'F'}, - {"0EVKSO", 'F'}, - {"0EVKV)", 'F'}, - {"0EVKVK", 'F'}, - {"0EVKVO", 'F'}, - {"0EVN", 'F'}, - {"0EVN)U", 'F'}, - {"0EVN;", 'F'}, - {"0EVN;C", 'F'}, - {"0EVNC", 'F'}, - {"0EVNKN", 'F'}, - {"0EVNO(", 'F'}, - {"0EVNOF", 'F'}, - {"0EVNOS", 'F'}, - {"0EVNOV", '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'}, - {"0EVOS;", 'F'}, - {"0EVOSB", 'F'}, - {"0EVOSF", 'F'}, - {"0EVOSK", 'F'}, - {"0EVOSU", 'F'}, - {"0EVOSV", 'F'}, - {"0EVS", 'F'}, - {"0EVS;", 'F'}, - {"0EVS;C", 'F'}, - {"0EVSC", 'F'}, - {"0EVSO(", 'F'}, - {"0EVSO1", 'F'}, - {"0EVSOF", 'F'}, - {"0EVSON", 'F'}, - {"0EVSOS", 'F'}, - {"0EVSOV", 'F'}, - {"0EVU(E", 'F'}, - {"0EVUE(", 'F'}, - {"0EVUE1", 'F'}, - {"0EVUEF", 'F'}, - {"0EVUEK", 'F'}, - {"0EVUEN", 'F'}, - {"0EVUES", 'F'}, - {"0EVUEV", '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(),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()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&1", 'F'}, - {"0F(1&F", 'F'}, - {"0F(1&N", 'F'}, - {"0F(1&S", 'F'}, - {"0F(1&V", '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(1O(", 'F'}, - {"0F(1OF", 'F'}, - {"0F(1OS", 'F'}, - {"0F(1OV", 'F'}, - {"0F(E(1", 'F'}, - {"0F(E(E", 'F'}, - {"0F(E(F", 'F'}, - {"0F(E(N", 'F'}, - {"0F(E(S", 'F'}, - {"0F(E(V", 'F'}, - {"0F(E1&", 'F'}, - {"0F(E1)", 'F'}, - {"0F(E1K", '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(EN&", 'F'}, - {"0F(EN)", 'F'}, - {"0F(ENK", 'F'}, - {"0F(ENO", 'F'}, - {"0F(ES&", 'F'}, - {"0F(ES)", 'F'}, - {"0F(ESK", 'F'}, - {"0F(ESO", 'F'}, - {"0F(EV&", 'F'}, - {"0F(EV)", 'F'}, - {"0F(EVK", 'F'}, - {"0F(EVO", 'F'}, - {"0F(F()", 'F'}, - {"0F(F(1", 'F'}, - {"0F(F(E", '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", 'F'}, - {"0F(N&(", 'F'}, - {"0F(N&1", 'F'}, - {"0F(N&F", 'F'}, - {"0F(N&N", 'F'}, - {"0F(N&S", 'F'}, - {"0F(N&V", '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(NO(", 'F'}, - {"0F(NOF", 'F'}, - {"0F(NOS", 'F'}, - {"0F(NOV", 'F'}, - {"0F(S&(", 'F'}, - {"0F(S&1", 'F'}, - {"0F(S&F", 'F'}, - {"0F(S&N", 'F'}, - {"0F(S&S", 'F'}, - {"0F(S&V", '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(SO(", 'F'}, - {"0F(SO1", 'F'}, - {"0F(SOF", 'F'}, - {"0F(SON", 'F'}, - {"0F(SOS", 'F'}, - {"0F(SOV", 'F'}, - {"0F(T,(", 'F'}, - {"0F(T,F", '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(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,F", 'F'}, - {"0F(VO(", 'F'}, - {"0F(VOF", 'F'}, - {"0F(VOS", '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(1", 'F'}, - {"0K(F(F", 'F'}, - {"0K(F(N", 'F'}, - {"0K(F(S", 'F'}, - {"0K(F(V", '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)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)A", 'F'}, - {"0K(V)K", 'F'}, - {"0K(V)O", 'F'}, - {"0K(VO(", 'F'}, - {"0K(VOF", 'F'}, - {"0K(VOS", 'F'}, - {"0K1,(1", 'F'}, - {"0K1,(F", 'F'}, - {"0K1,(N", 'F'}, - {"0K1,(S", 'F'}, - {"0K1,(V", 'F'}, - {"0K1,F(", 'F'}, - {"0K1A(F", 'F'}, - {"0K1A(N", 'F'}, - {"0K1A(S", 'F'}, - {"0K1A(V", 'F'}, - {"0K1AF(", 'F'}, - {"0K1ASO", 'F'}, - {"0K1AVO", '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(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'}, - {"0K1OSV", 'F'}, - {"0K1OV(", 'F'}, - {"0K1OV,", 'F'}, - {"0K1OVA", 'F'}, - {"0K1OVF", 'F'}, - {"0K1OVK", 'F'}, - {"0K1OVO", 'F'}, - {"0K1OVS", '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,(1", 'F'}, - {"0KN,(F", 'F'}, - {"0KN,(N", 'F'}, - {"0KN,(S", 'F'}, - {"0KN,(V", 'F'}, - {"0KN,F(", 'F'}, - {"0KNA(F", 'F'}, - {"0KNA(N", 'F'}, - {"0KNA(S", 'F'}, - {"0KNA(V", 'F'}, - {"0KNAF(", 'F'}, - {"0KNASO", 'F'}, - {"0KNAVO", '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,(1", 'F'}, - {"0KS,(F", 'F'}, - {"0KS,(N", 'F'}, - {"0KS,(S", 'F'}, - {"0KS,(V", 'F'}, - {"0KS,F(", 'F'}, - {"0KSA(F", 'F'}, - {"0KSA(N", 'F'}, - {"0KSA(S", 'F'}, - {"0KSA(V", 'F'}, - {"0KSAF(", 'F'}, - {"0KSASO", 'F'}, - {"0KSAVO", '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(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'}, - {"0KSO1S", 'F'}, - {"0KSO1V", 'F'}, - {"0KSOF(", 'F'}, - {"0KSON(", 'F'}, - {"0KSON,", 'F'}, - {"0KSON1", 'F'}, - {"0KSONA", 'F'}, - {"0KSONF", 'F'}, - {"0KSONK", 'F'}, - {"0KSOS(", 'F'}, - {"0KSOS,", 'F'}, - {"0KSOS1", 'F'}, - {"0KSOSA", 'F'}, - {"0KSOSF", 'F'}, - {"0KSOSK", 'F'}, - {"0KSOSV", 'F'}, - {"0KSOV(", 'F'}, - {"0KSOV,", 'F'}, - {"0KSOVA", 'F'}, - {"0KSOVF", 'F'}, - {"0KSOVK", 'F'}, - {"0KSOVO", 'F'}, - {"0KSOVS", 'F'}, - {"0KV,(1", 'F'}, - {"0KV,(F", 'F'}, - {"0KV,(N", 'F'}, - {"0KV,(S", 'F'}, - {"0KV,(V", 'F'}, - {"0KV,F(", 'F'}, - {"0KVA(F", 'F'}, - {"0KVA(N", 'F'}, - {"0KVA(S", 'F'}, - {"0KVA(V", 'F'}, - {"0KVAF(", 'F'}, - {"0KVASO", 'F'}, - {"0KVAVO", '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(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'}, - {"0KVOSV", '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&(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)C", 'F'}, - {"0N&1)O", '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(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(1", 'F'}, - {"0N&F(E", '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(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)C", 'F'}, - {"0N&N)O", '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)C", 'F'}, - {"0N&S)O", '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)C", 'F'}, - {"0N&V)O", '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(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(EF(", 'F'}, - {"0N(EKF", 'F'}, - {"0N(EKN", 'F'}, - {"0N(ENK", '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)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(E", '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)&(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),(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(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(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(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(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)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)ONU", 'F'}, - {"0N)OS", 'F'}, - {"0N)OS&", 'F'}, - {"0N)OS)", 'F'}, - {"0N)OS;", 'F'}, - {"0N)OSB", 'F'}, - {"0N)OSC", 'F'}, - {"0N)OSK", '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(E", 'F'}, - {"0N)UE(", 'F'}, - {"0N)UE1", 'F'}, - {"0N)UEF", 'F'}, - {"0N)UEK", 'F'}, - {"0N)UEN", 'F'}, - {"0N)UES", 'F'}, - {"0N)UEV", '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(1", 'F'}, - {"0N,F(F", 'F'}, - {"0N,F(N", 'F'}, - {"0N,F(S", 'F'}, - {"0N,F(V", 'F'}, - {"0N1F()", 'F'}, - {"0N1F(1", 'F'}, - {"0N1F(F", 'F'}, - {"0N1F(N", 'F'}, - {"0N1F(S", 'F'}, - {"0N1F(V", 'F'}, - {"0N1O(1", 'F'}, - {"0N1O(F", 'F'}, - {"0N1O(N", 'F'}, - {"0N1O(S", 'F'}, - {"0N1O(V", 'F'}, - {"0N1OF(", 'F'}, - {"0N1OS(", 'F'}, - {"0N1OS1", 'F'}, - {"0N1OSF", '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(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;E1K", '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;ENE", 'F'}, - {"0N;ENK", 'F'}, - {"0N;ENO", 'F'}, - {"0N;ENT", 'F'}, - {"0N;ES,", 'F'}, - {"0N;ES;", 'F'}, - {"0N;ESC", 'F'}, - {"0N;ESK", 'F'}, - {"0N;ESO", 'F'}, - {"0N;EST", 'F'}, - {"0N;EV,", 'F'}, - {"0N;EV;", 'F'}, - {"0N;EVC", 'F'}, - {"0N;EVK", 'F'}, - {"0N;EVO", 'F'}, - {"0N;EVT", 'F'}, - {"0N;N: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;T1K", '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;TSK", '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;TVK", 'F'}, - {"0N;TVO", 'F'}, - {"0N;TVT", '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(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(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;", '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(1", 'F'}, - {"0NBE(F", 'F'}, - {"0NBE(N", 'F'}, - {"0NBE(S", 'F'}, - {"0NBE(V", 'F'}, - {"0NBEK(", '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;", '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;", '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,F", '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(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(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(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()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(E(", 'F'}, - {"0NF(E1", 'F'}, - {"0NF(EF", 'F'}, - {"0NF(EK", 'F'}, - {"0NF(EN", 'F'}, - {"0NF(ES", 'F'}, - {"0NF(EV", '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(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);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(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(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(S&", 'F'}, - {"0NO(S)", 'F'}, - {"0NO(S,", 'F'}, - {"0NO(SO", 'F'}, - {"0NO(V&", 'F'}, - {"0NO(V)", 'F'}, - {"0NO(V,", 'F'}, - {"0NO(VO", '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(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(E", 'F'}, - {"0NOS(U", 'F'}, - {"0NOS)&", 'F'}, - {"0NOS),", 'F'}, - {"0NOS);", 'F'}, - {"0NOS)B", 'F'}, - {"0NOS)C", 'F'}, - {"0NOS)E", 'F'}, - {"0NOS)K", 'F'}, - {"0NOS)O", 'F'}, - {"0NOS)U", 'F'}, - {"0NOS,(", 'F'}, - {"0NOS,F", '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'}, - {"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'}, - {"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(E", 'F'}, - {"0NOV(U", 'F'}, - {"0NOV)&", 'F'}, - {"0NOV),", 'F'}, - {"0NOV);", 'F'}, - {"0NOV)B", 'F'}, - {"0NOV)C", 'F'}, - {"0NOV)E", 'F'}, - {"0NOV)K", 'F'}, - {"0NOV)O", 'F'}, - {"0NOV)U", 'F'}, - {"0NOV,(", 'F'}, - {"0NOV,F", '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'}, - {"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(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'}, - {"0NU1C", 'F'}, - {"0NU1O(", 'F'}, - {"0NU1OF", 'F'}, - {"0NU1OS", 'F'}, - {"0NU1OV", 'F'}, - {"0NU;", 'F'}, - {"0NU;C", 'F'}, - {"0NUC", '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(1", 'F'}, - {"0NUF(F", 'F'}, - {"0NUF(N", 'F'}, - {"0NUF(S", 'F'}, - {"0NUF(V", 'F'}, - {"0NUK(E", 'F'}, - {"0NUN(1", 'F'}, - {"0NUN(F", 'F'}, - {"0NUN(S", 'F'}, - {"0NUN(V", 'F'}, - {"0NUN,(", 'F'}, - {"0NUN,F", '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(E", 'F'}, - {"0NUON(", 'F'}, - {"0NUON1", 'F'}, - {"0NUONF", 'F'}, - {"0NUONS", 'F'}, - {"0NUS,(", 'F'}, - {"0NUS,F", '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,F", 'F'}, - {"0NUVC", 'F'}, - {"0NUVO(", 'F'}, - {"0NUVOF", 'F'}, - {"0NUVOS", 'F'}, - {"0O(1)O", 'F'}, - {"0O(1)U", 'F'}, - {"0O(1O(", 'F'}, - {"0O(1OF", 'F'}, - {"0O(1OS", 'F'}, - {"0O(1OV", 'F'}, - {"0O(F()", 'F'}, - {"0O(F(1", 'F'}, - {"0O(F(F", 'F'}, - {"0O(F(N", 'F'}, - {"0O(F(S", 'F'}, - {"0O(F(V", 'F'}, - {"0O(N)O", 'F'}, - {"0O(N)U", 'F'}, - {"0O(NO(", 'F'}, - {"0O(NOF", 'F'}, - {"0O(NOS", 'F'}, - {"0O(NOV", 'F'}, - {"0O(S)O", 'F'}, - {"0O(S)U", 'F'}, - {"0O(SO(", 'F'}, - {"0O(SO1", 'F'}, - {"0O(SOF", 'F'}, - {"0O(SON", 'F'}, - {"0O(SOS", 'F'}, - {"0O(SOV", 'F'}, - {"0O(V)O", 'F'}, - {"0O(V)U", 'F'}, - {"0O(VO(", 'F'}, - {"0O(VOF", 'F'}, - {"0O(VOS", 'F'}, - {"0O1UE(", 'F'}, - {"0O1UE1", 'F'}, - {"0O1UEF", 'F'}, - {"0O1UEK", 'F'}, - {"0O1UEN", 'F'}, - {"0O1UES", 'F'}, - {"0O1UEV", 'F'}, - {"0OF()O", 'F'}, - {"0OF()U", 'F'}, - {"0OF(1)", 'F'}, - {"0OF(1O", 'F'}, - {"0OF(F(", 'F'}, - {"0OF(N)", 'F'}, - {"0OF(NO", 'F'}, - {"0OF(S)", 'F'}, - {"0OF(SO", 'F'}, - {"0OF(V)", 'F'}, - {"0OF(VO", 'F'}, - {"0ONUE(", 'F'}, - {"0ONUE1", 'F'}, - {"0ONUEF", 'F'}, - {"0ONUEK", 'F'}, - {"0ONUEN", 'F'}, - {"0ONUES", 'F'}, - {"0ONUEV", 'F'}, - {"0OSUE(", 'F'}, - {"0OSUE1", 'F'}, - {"0OSUEF", 'F'}, - {"0OSUEK", 'F'}, - {"0OSUEN", 'F'}, - {"0OSUES", 'F'}, - {"0OSUEV", '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'}, - {"0OVO(1", 'F'}, - {"0OVO(F", 'F'}, - {"0OVO(N", 'F'}, - {"0OVO(S", 'F'}, - {"0OVO(V", 'F'}, - {"0OVOF(", 'F'}, - {"0OVOSU", 'F'}, - {"0OVUE(", 'F'}, - {"0OVUE1", 'F'}, - {"0OVUEF", 'F'}, - {"0OVUEK", 'F'}, - {"0OVUEN", 'F'}, - {"0OVUES", 'F'}, - {"0OVUEV", '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)C", 'F'}, - {"0S&1)O", '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&1TN", 'F'}, - {"0S&1U", 'F'}, - {"0S&1U(", 'F'}, - {"0S&1U;", 'F'}, - {"0S&1UC", 'F'}, - {"0S&1UE", '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(1", 'F'}, - {"0S&F(E", '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(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)C", 'F'}, - {"0S&N)O", '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)C", 'F'}, - {"0S&S)O", '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)C", 'F'}, - {"0S&V)O", '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(EF(", 'F'}, - {"0S(EKF", 'F'}, - {"0S(EKN", 'F'}, - {"0S(ENK", 'F'}, - {"0S(U(E", '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),(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(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)C", '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(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(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)O1U", 'F'}, - {"0S)OF(", 'F'}, - {"0S)ON&", 'F'}, - {"0S)ON)", 'F'}, - {"0S)ON;", 'F'}, - {"0S)ONB", 'F'}, - {"0S)ONC", 'F'}, - {"0S)ONK", '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)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(E", 'F'}, - {"0S)UE(", 'F'}, - {"0S)UE1", 'F'}, - {"0S)UEF", 'F'}, - {"0S)UEK", 'F'}, - {"0S)UEN", 'F'}, - {"0S)UES", 'F'}, - {"0S)UEV", '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(1", 'F'}, - {"0S,F(F", 'F'}, - {"0S,F(N", 'F'}, - {"0S,F(S", 'F'}, - {"0S,F(V", 'F'}, - {"0S1F()", 'F'}, - {"0S1F(1", 'F'}, - {"0S1F(F", 'F'}, - {"0S1F(N", 'F'}, - {"0S1F(S", 'F'}, - {"0S1F(V", 'F'}, - {"0S1NC", 'F'}, - {"0S1O(1", 'F'}, - {"0S1O(F", 'F'}, - {"0S1O(N", 'F'}, - {"0S1O(S", 'F'}, - {"0S1O(V", 'F'}, - {"0S1OF(", 'F'}, - {"0S1OS(", 'F'}, - {"0S1OS1", 'F'}, - {"0S1OSF", '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(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;E1K", '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;ENE", 'F'}, - {"0S;ENK", 'F'}, - {"0S;ENO", 'F'}, - {"0S;ENT", 'F'}, - {"0S;ES,", 'F'}, - {"0S;ES;", 'F'}, - {"0S;ESC", 'F'}, - {"0S;ESK", 'F'}, - {"0S;ESO", 'F'}, - {"0S;EST", 'F'}, - {"0S;EV,", 'F'}, - {"0S;EV;", 'F'}, - {"0S;EVC", 'F'}, - {"0S;EVK", 'F'}, - {"0S;EVO", 'F'}, - {"0S;EVT", 'F'}, - {"0S;N: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;T1K", '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;TSK", '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;TVK", 'F'}, - {"0S;TVO", 'F'}, - {"0S;TVT", '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(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(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;", '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(1", 'F'}, - {"0SBE(F", 'F'}, - {"0SBE(N", 'F'}, - {"0SBE(S", 'F'}, - {"0SBE(V", 'F'}, - {"0SBEK(", '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;", '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;", '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,F", '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(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(1", 'F'}, - {"0SEF(F", 'F'}, - {"0SEF(N", 'F'}, - {"0SEF(S", 'F'}, - {"0SEF(V", '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(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()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(E(", 'F'}, - {"0SF(E1", 'F'}, - {"0SF(EF", 'F'}, - {"0SF(EK", 'F'}, - {"0SF(EN", 'F'}, - {"0SF(ES", 'F'}, - {"0SF(EV", '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(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);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(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(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(S&", 'F'}, - {"0SO(S)", 'F'}, - {"0SO(S,", 'F'}, - {"0SO(SO", '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(E", 'F'}, - {"0SO1(U", 'F'}, - {"0SO1)&", 'F'}, - {"0SO1),", 'F'}, - {"0SO1);", 'F'}, - {"0SO1)B", 'F'}, - {"0SO1)C", 'F'}, - {"0SO1)E", 'F'}, - {"0SO1)K", 'F'}, - {"0SO1)O", 'F'}, - {"0SO1)U", 'F'}, - {"0SO1,(", 'F'}, - {"0SO1,F", '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'}, - {"0SO1NU", '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(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(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(1", 'F'}, - {"0SON(E", 'F'}, - {"0SON(F", 'F'}, - {"0SON(S", 'F'}, - {"0SON(U", 'F'}, - {"0SON(V", 'F'}, - {"0SON)&", 'F'}, - {"0SON),", 'F'}, - {"0SON);", 'F'}, - {"0SON)B", 'F'}, - {"0SON)C", 'F'}, - {"0SON)E", 'F'}, - {"0SON)K", 'F'}, - {"0SON)O", 'F'}, - {"0SON)U", 'F'}, - {"0SON,(", 'F'}, - {"0SON,F", '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'}, - {"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(E", 'F'}, - {"0SOS(U", 'F'}, - {"0SOS)&", 'F'}, - {"0SOS),", 'F'}, - {"0SOS);", 'F'}, - {"0SOS)B", 'F'}, - {"0SOS)C", 'F'}, - {"0SOS)E", 'F'}, - {"0SOS)K", 'F'}, - {"0SOS)O", 'F'}, - {"0SOS)U", 'F'}, - {"0SOS,(", 'F'}, - {"0SOS,F", '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'}, - {"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'}, - {"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(E", 'F'}, - {"0SOV(U", 'F'}, - {"0SOV)&", 'F'}, - {"0SOV),", 'F'}, - {"0SOV);", 'F'}, - {"0SOV)B", 'F'}, - {"0SOV)C", 'F'}, - {"0SOV)E", 'F'}, - {"0SOV)K", 'F'}, - {"0SOV)O", 'F'}, - {"0SOV)U", 'F'}, - {"0SOV,(", 'F'}, - {"0SOV,F", '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'}, - {"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(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'}, - {"0SU1C", 'F'}, - {"0SU1O(", 'F'}, - {"0SU1OF", 'F'}, - {"0SU1OS", 'F'}, - {"0SU1OV", 'F'}, - {"0SU;", 'F'}, - {"0SU;C", 'F'}, - {"0SUC", '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(1", 'F'}, - {"0SUF(F", 'F'}, - {"0SUF(N", 'F'}, - {"0SUF(S", 'F'}, - {"0SUF(V", 'F'}, - {"0SUK(E", 'F'}, - {"0SUN(1", 'F'}, - {"0SUN(F", 'F'}, - {"0SUN(S", 'F'}, - {"0SUN(V", 'F'}, - {"0SUN,(", 'F'}, - {"0SUN,F", '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(E", 'F'}, - {"0SUON(", 'F'}, - {"0SUON1", 'F'}, - {"0SUONF", 'F'}, - {"0SUONS", 'F'}, - {"0SUS,(", 'F'}, - {"0SUS,F", '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,F", 'F'}, - {"0SUVC", 'F'}, - {"0SUVO(", 'F'}, - {"0SUVOF", 'F'}, - {"0SUVOS", 'F'}, - {"0SVF()", 'F'}, - {"0SVF(1", 'F'}, - {"0SVF(F", 'F'}, - {"0SVF(N", 'F'}, - {"0SVF(S", 'F'}, - {"0SVF(V", 'F'}, - {"0SVO(1", 'F'}, - {"0SVO(F", 'F'}, - {"0SVO(N", 'F'}, - {"0SVO(S", 'F'}, - {"0SVO(V", 'F'}, - {"0SVOF(", 'F'}, - {"0SVOS(", 'F'}, - {"0SVOS1", 'F'}, - {"0SVOSF", '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(1)F", 'F'}, - {"0T(1)O", 'F'}, - {"0T(1F(", 'F'}, - {"0T(1N)", '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(1", 'F'}, - {"0T(F(F", 'F'}, - {"0T(F(N", 'F'}, - {"0T(F(S", 'F'}, - {"0T(F(V", 'F'}, - {"0T(N(1", 'F'}, - {"0T(N(F", 'F'}, - {"0T(N(S", 'F'}, - {"0T(N(V", 'F'}, - {"0T(N)F", 'F'}, - {"0T(N)O", '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", 'F'}, - {"0T(S)O", '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", 'F'}, - {"0T(V)O", 'F'}, - {"0T(VF(", 'F'}, - {"0T(VO(", 'F'}, - {"0T(VOF", 'F'}, - {"0T(VOS", 'F'}, - {"0T(VS)", 'F'}, - {"0T(VSO", 'F'}, - {"0T(VV)", 'F'}, - {"0T1F(1", 'F'}, - {"0T1F(F", 'F'}, - {"0T1F(N", 'F'}, - {"0T1F(S", 'F'}, - {"0T1F(V", 'F'}, - {"0T1O(1", 'F'}, - {"0T1O(F", 'F'}, - {"0T1O(N", 'F'}, - {"0T1O(S", 'F'}, - {"0T1O(V", 'F'}, - {"0T1OF(", 'F'}, - {"0T1OSF", 'F'}, - {"0T1OVF", 'F'}, - {"0T1OVO", '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(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(1", 'F'}, - {"0TNF(F", 'F'}, - {"0TNF(N", 'F'}, - {"0TNF(S", 'F'}, - {"0TNF(V", 'F'}, - {"0TNO(1", 'F'}, - {"0TNO(F", 'F'}, - {"0TNO(N", 'F'}, - {"0TNO(S", 'F'}, - {"0TNO(V", 'F'}, - {"0TNOF(", 'F'}, - {"0TNOSF", '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'}, - {"0TSF(1", 'F'}, - {"0TSF(F", 'F'}, - {"0TSF(N", 'F'}, - {"0TSF(S", 'F'}, - {"0TSF(V", 'F'}, - {"0TSO(1", 'F'}, - {"0TSO(F", 'F'}, - {"0TSO(N", 'F'}, - {"0TSO(S", 'F'}, - {"0TSO(V", 'F'}, - {"0TSO1F", 'F'}, - {"0TSOF(", 'F'}, - {"0TSONF", 'F'}, - {"0TSOSF", 'F'}, - {"0TSOVF", 'F'}, - {"0TSOVO", 'F'}, - {"0TVF(1", 'F'}, - {"0TVF(F", 'F'}, - {"0TVF(N", 'F'}, - {"0TVF(S", 'F'}, - {"0TVF(V", 'F'}, - {"0TVO(1", 'F'}, - {"0TVO(F", 'F'}, - {"0TVO(N", 'F'}, - {"0TVO(S", 'F'}, - {"0TVO(V", 'F'}, - {"0TVOF(", 'F'}, - {"0TVOSF", '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(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;", '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(1", 'F'}, - {"0UEF(F", 'F'}, - {"0UEF(N", 'F'}, - {"0UEF(S", 'F'}, - {"0UEF(V", '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", '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;", '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,F", '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(1O", 'F'}, - {"0UF(F(", 'F'}, - {"0UF(NO", 'F'}, - {"0UF(SO", 'F'}, - {"0UF(VO", '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)C", 'F'}, - {"0V&1)O", '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(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(1", 'F'}, - {"0V&F(E", '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(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)C", 'F'}, - {"0V&N)O", '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)C", 'F'}, - {"0V&S)O", '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)C", 'F'}, - {"0V&V)O", '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(EF(", 'F'}, - {"0V(EKF", 'F'}, - {"0V(EKN", 'F'}, - {"0V(ENK", 'F'}, - {"0V(U(E", '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),(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(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)C", '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(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(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)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)ONU", 'F'}, - {"0V)OS", 'F'}, - {"0V)OS&", 'F'}, - {"0V)OS)", 'F'}, - {"0V)OS;", 'F'}, - {"0V)OSB", 'F'}, - {"0V)OSC", 'F'}, - {"0V)OSK", '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(E", 'F'}, - {"0V)UE(", 'F'}, - {"0V)UE1", 'F'}, - {"0V)UEF", 'F'}, - {"0V)UEK", 'F'}, - {"0V)UEN", 'F'}, - {"0V)UES", 'F'}, - {"0V)UEV", '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,F()", 'F'}, - {"0V,F(1", 'F'}, - {"0V,F(F", 'F'}, - {"0V,F(N", 'F'}, - {"0V,F(S", 'F'}, - {"0V,F(V", '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;E1K", '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;ENE", 'F'}, - {"0V;ENK", 'F'}, - {"0V;ENO", 'F'}, - {"0V;ENT", 'F'}, - {"0V;ES,", 'F'}, - {"0V;ES;", 'F'}, - {"0V;ESC", 'F'}, - {"0V;ESK", 'F'}, - {"0V;ESO", 'F'}, - {"0V;EST", 'F'}, - {"0V;EV,", 'F'}, - {"0V;EV;", 'F'}, - {"0V;EVC", 'F'}, - {"0V;EVK", 'F'}, - {"0V;EVO", 'F'}, - {"0V;EVT", 'F'}, - {"0V;N: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;T1K", '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;TSK", '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;TVK", 'F'}, - {"0V;TVO", 'F'}, - {"0V;TVT", '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(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(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;", '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(1", 'F'}, - {"0VBE(F", 'F'}, - {"0VBE(N", 'F'}, - {"0VBE(S", 'F'}, - {"0VBE(V", 'F'}, - {"0VBEK(", '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;", '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;", '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,F", '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(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(1", 'F'}, - {"0VEF(F", 'F'}, - {"0VEF(N", 'F'}, - {"0VEF(S", 'F'}, - {"0VEF(V", '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(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()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(E(", 'F'}, - {"0VF(E1", 'F'}, - {"0VF(EF", 'F'}, - {"0VF(EK", 'F'}, - {"0VF(EN", 'F'}, - {"0VF(ES", 'F'}, - {"0VF(EV", '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(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);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(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(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(S&", 'F'}, - {"0VO(S)", 'F'}, - {"0VO(S,", 'F'}, - {"0VO(SO", 'F'}, - {"0VO(V&", 'F'}, - {"0VO(V)", 'F'}, - {"0VO(V,", 'F'}, - {"0VO(VO", '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(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(E", 'F'}, - {"0VOS(U", 'F'}, - {"0VOS)&", 'F'}, - {"0VOS),", 'F'}, - {"0VOS);", 'F'}, - {"0VOS)B", 'F'}, - {"0VOS)C", 'F'}, - {"0VOS)E", 'F'}, - {"0VOS)K", 'F'}, - {"0VOS)O", 'F'}, - {"0VOS)U", 'F'}, - {"0VOS,(", 'F'}, - {"0VOS,F", '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'}, - {"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'}, - {"0VOU(E", 'F'}, - {"0VOUEK", 'F'}, - {"0VOUEN", 'F'}, - {"0VU", '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'}, - {"0VU1C", 'F'}, - {"0VU1O(", 'F'}, - {"0VU1OF", 'F'}, - {"0VU1OS", 'F'}, - {"0VU1OV", 'F'}, - {"0VU;", 'F'}, - {"0VU;C", 'F'}, - {"0VUC", '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(1", 'F'}, - {"0VUF(F", 'F'}, - {"0VUF(N", 'F'}, - {"0VUF(S", 'F'}, - {"0VUF(V", 'F'}, - {"0VUK(E", 'F'}, - {"0VUN(1", 'F'}, - {"0VUN(F", 'F'}, - {"0VUN(S", 'F'}, - {"0VUN(V", 'F'}, - {"0VUN,(", 'F'}, - {"0VUN,F", '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(E", 'F'}, - {"0VUON(", 'F'}, - {"0VUON1", 'F'}, - {"0VUONF", 'F'}, - {"0VUONS", 'F'}, - {"0VUS,(", 'F'}, - {"0VUS,F", '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,F", '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", '&'}, - {"ANY", 'f'}, - {"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_BASE64", 'f'}, - {"FROM_DAYS", 'f'}, - {"FROM_UNIXTIME", 'f'}, - {"FULL JOIN", 'k'}, - {"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'}, - {"IF NOT", 'n'}, - {"IF NOT 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 FULL OUTER JOIN", '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'}, - {"NATURAL RIGHT OUTER JOIN", '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_INSTR", 'f'}, - {"REGEXP_MATCHES", 'f'}, - {"REGEXP_REPLACE", 'f'}, - {"REGEXP_SPLIT_TO_ARRAY", 'f'}, - {"REGEXP_SPLIT_TO_TABLE", 'f'}, - {"REGEXP_SUBSTR", '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'}, - {"SOME", 'f'}, - {"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_BASE64", '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 = 9049; -#endif diff --git a/naxsi_src/ext/libinjection/libinjection_xss.c b/naxsi_src/ext/libinjection/libinjection_xss.c deleted file mode 100644 index 17c5346..0000000 --- a/naxsi_src/ext/libinjection/libinjection_xss.c +++ /dev/null @@ -1,531 +0,0 @@ - -#include "libinjection.h" -#include "libinjection_xss.h" -#include "libinjection_html5.h" - -#include -#include - -typedef enum attribute { - TYPE_NONE - , TYPE_BLACK /* ban always */ - , TYPE_ATTR_URL /* attribute value takes a URL-like object */ - , TYPE_STYLE - , TYPE_ATTR_INDIRECT /* attribute *name* is given in *value* */ -} attribute_t; - - -static attribute_t is_black_attr(const char* s, size_t len); -static int is_black_tag(const char* s, size_t len); -static int is_black_url(const char* s, size_t len); -static int cstrcasecmp_with_null(const char *a, const char *b, size_t n); -static int html_decode_char_at(const char* src, size_t len, size_t* consumed); -static int htmlencode_startswith(const char* prefix, const char *src, size_t n); - - -typedef struct stringtype { - const char* name; - attribute_t atype; -} stringtype_t; - - -static const int gsHexDecodeMap[256] = { - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256, - 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256 -}; - -static int html_decode_char_at(const char* src, size_t len, size_t* consumed) -{ - int val = 0; - size_t i; - int ch; - - if (len == 0 || src == NULL) { - *consumed = 0; - return -1; - } - - *consumed = 1; - if (*src != '&' || len < 2) { - return (unsigned char)(*src); - } - - - if (*(src+1) != '#') { - /* normally this would be for named entities - * but for this case we don't actually care - */ - return '&'; - } - - if (*(src+2) == 'x' || *(src+2) == 'X') { - ch = (unsigned char) (*(src+3)); - ch = gsHexDecodeMap[ch]; - if (ch == 256) { - /* degenerate case '&#[?]' */ - return '&'; - } - val = ch; - i = 4; - while (i < len) { - ch = (unsigned char) src[i]; - if (ch == ';') { - *consumed = i + 1; - return val; - } - ch = gsHexDecodeMap[ch]; - if (ch == 256) { - *consumed = i; - return val; - } - val = (val * 16) + ch; - if (val > 0x1000FF) { - return '&'; - } - ++i; - } - *consumed = i; - return val; - } else { - i = 2; - ch = (unsigned char) src[i]; - if (ch < '0' || ch > '9') { - return '&'; - } - val = ch - '0'; - i += 1; - while (i < len) { - ch = (unsigned char) src[i]; - if (ch == ';') { - *consumed = i + 1; - return val; - } - if (ch < '0' || ch > '9') { - *consumed = i; - return val; - } - val = (val * 10) + (ch - '0'); - if (val > 0x1000FF) { - return '&'; - } - ++i; - } - *consumed = i; - return val; - } -} - - -/* - * view-source: - * data: - * javascript: - */ -static stringtype_t BLACKATTR[] = { - { "ACTION", TYPE_ATTR_URL } /* form */ - , { "ATTRIBUTENAME", TYPE_ATTR_INDIRECT } /* SVG allow indirection of attribute names */ - , { "BY", TYPE_ATTR_URL } /* SVG */ - , { "BACKGROUND", TYPE_ATTR_URL } /* IE6, O11 */ - , { "DATAFORMATAS", TYPE_BLACK } /* IE */ - , { "DATASRC", TYPE_BLACK } /* IE */ - , { "DYNSRC", TYPE_ATTR_URL } /* Obsolete img attribute */ - , { "FILTER", TYPE_STYLE } /* Opera, SVG inline style */ - , { "FORMACTION", TYPE_ATTR_URL } /* HTML5 */ - , { "FOLDER", TYPE_ATTR_URL } /* Only on A tags, IE-only */ - , { "FROM", TYPE_ATTR_URL } /* SVG */ - , { "HANDLER", TYPE_ATTR_URL } /* SVG Tiny, Opera */ - , { "HREF", TYPE_ATTR_URL } - , { "LOWSRC", TYPE_ATTR_URL } /* Obsolete img attribute */ - , { "POSTER", TYPE_ATTR_URL } /* Opera 10,11 */ - , { "SRC", TYPE_ATTR_URL } - , { "STYLE", TYPE_STYLE } - , { "TO", TYPE_ATTR_URL } /* SVG */ - , { "VALUES", TYPE_ATTR_URL } /* SVG */ - , { "XLINK:HREF", TYPE_ATTR_URL } - , { NULL, TYPE_NONE } -}; - -/* xmlns */ -/* xml-stylesheet > , */ - -/* - static const char* BLACKATTR[] = { - "ATTRIBUTENAME", - "BACKGROUND", - "DATAFORMATAS", - "HREF", - "SCROLL", - "SRC", - "STYLE", - "SRCDOC", - NULL - }; -*/ - -static const char* BLACKTAG[] = { - "APPLET" - /* , "AUDIO" */ - , "BASE" - , "COMMENT" /* IE http://html5sec.org/#38 */ - , "EMBED" - /* , "FORM" */ - , "FRAME" - , "FRAMESET" - , "HANDLER" /* Opera SVG, effectively a script tag */ - , "IFRAME" - , "IMPORT" - , "ISINDEX" - , "LINK" - , "LISTENER" - /* , "MARQUEE" */ - , "META" - , "NOSCRIPT" - , "OBJECT" - , "SCRIPT" - , "STYLE" - /* , "VIDEO" */ - , "VMLFRAME" - , "XML" - , "XSS" - , NULL -}; - - -static int cstrcasecmp_with_null(const char *a, const char *b, size_t n) -{ - char ca; - char cb; - /* printf("Comparing to %s %.*s\n", a, (int)n, b); */ - while (n-- > 0) { - cb = *b++; - if (cb == '\0') continue; - - ca = *a++; - - if (cb >= 'a' && cb <= 'z') { - cb -= 0x20; - } - /* printf("Comparing %c vs %c with %d left\n", ca, cb, (int)n); */ - if (ca != cb) { - return 1; - } - } - - if (*a == 0) { - /* printf(" MATCH \n"); */ - return 0; - } else { - return 1; - } -} - -/* - * Does an HTML encoded binary string (const char*, lenght) start with - * a all uppercase c-string (null terminated), case insenstive! - * - * also ignore any embedded nulls in the HTML string! - * - * return 1 if match / starts with - * return 0 if not - */ -static int htmlencode_startswith(const char *a, const char *b, size_t n) -{ - size_t consumed; - int cb; - int first = 1; - /* printf("Comparing %s with %.*s\n", a,(int)n,b); */ - while (n > 0) { - if (*a == 0) { - /* printf("Match EOL!\n"); */ - return 1; - } - cb = html_decode_char_at(b, n, &consumed); - b += consumed; - n -= consumed; - - if (first && cb <= 32) { - /* ignore all leading whitespace and control characters */ - continue; - } - first = 0; - - if (cb == 0) { - /* always ignore null characters in user input */ - continue; - } - - if (cb == 10) { - /* always ignore vtab characters in user input */ - /* who allows this?? */ - continue; - } - - if (cb >= 'a' && cb <= 'z') { - /* upcase */ - cb -= 0x20; - } - - if (*a != (char) cb) { - /* printf(" %c != %c\n", *a, cb); */ - /* mismatch */ - return 0; - } - a++; - } - - return (*a == 0) ? 1 : 0; -} - -static int is_black_tag(const char* s, size_t len) -{ - const char** black; - - if (len < 3) { - return 0; - } - - black = BLACKTAG; - while (*black != NULL) { - if (cstrcasecmp_with_null(*black, s, len) == 0) { - /* printf("Got black tag %s\n", *black); */ - return 1; - } - black += 1; - } - - /* anything SVG related */ - if ((s[0] == 's' || s[0] == 'S') && - (s[1] == 'v' || s[1] == 'V') && - (s[2] == 'g' || s[2] == 'G')) { - /* printf("Got SVG tag \n"); */ - return 1; - } - - /* Anything XSL(t) related */ - if ((s[0] == 'x' || s[0] == 'X') && - (s[1] == 's' || s[1] == 'S') && - (s[2] == 'l' || s[2] == 'L')) { - /* printf("Got XSL tag\n"); */ - return 1; - } - - return 0; -} - -static attribute_t is_black_attr(const char* s, size_t len) -{ - stringtype_t* black; - - if (len < 2) { - return TYPE_NONE; - } - - /* javascript on.* */ - if ((s[0] == 'o' || s[0] == 'O') && (s[1] == 'n' || s[1] == 'N')) { - /* printf("Got javascript on- attribute name\n"); */ - return TYPE_BLACK; - } - - - if (len >= 5) { - /* XMLNS can be used to create arbitrary tags */ - if (cstrcasecmp_with_null("XMLNS", s, 5) == 0 || cstrcasecmp_with_null("XLINK", s, 5) == 0) { - /* printf("Got XMLNS and XLINK tags\n"); */ - return TYPE_BLACK; - } - } - - black = BLACKATTR; - while (black->name != NULL) { - if (cstrcasecmp_with_null(black->name, s, len) == 0) { - /* printf("Got banned attribute name %s\n", black->name); */ - return black->atype; - } - black += 1; - } - - return TYPE_NONE; -} - -static int is_black_url(const char* s, size_t len) -{ - - static const char* data_url = "DATA"; - static const char* viewsource_url = "VIEW-SOURCE"; - - /* obsolete but interesting signal */ - static const char* vbscript_url = "VBSCRIPT"; - - /* covers JAVA, JAVASCRIPT, + colon */ - static const char* javascript_url = "JAVA"; - - /* skip whitespace */ - while (len > 0 && (*s <= 32 || *s >= 127)) { - /* - * HEY: this is a signed character. - * We are intentionally skipping high-bit characters too - * since they are not ascii, and Opera sometimes uses UTF8 whitespace. - * - * Also in EUC-JP some of the high bytes are just ignored. - */ - ++s; - --len; - } - - if (htmlencode_startswith(data_url, s, len)) { - return 1; - } - - if (htmlencode_startswith(viewsource_url, s, len)) { - return 1; - } - - if (htmlencode_startswith(javascript_url, s, len)) { - return 1; - } - - if (htmlencode_startswith(vbscript_url, s, len)) { - return 1; - } - return 0; -} - -int libinjection_is_xss(const char* s, size_t len, int flags) -{ - h5_state_t h5; - attribute_t attr = TYPE_NONE; - - libinjection_h5_init(&h5, s, len, (enum html5_flags) flags); - while (libinjection_h5_next(&h5)) { - if (h5.token_type != ATTR_VALUE) { - attr = TYPE_NONE; - } - - if (h5.token_type == DOCTYPE) { - return 1; - } else if (h5.token_type == TAG_NAME_OPEN) { - if (is_black_tag(h5.token_start, h5.token_len)) { - return 1; - } - } else if (h5.token_type == ATTR_NAME) { - attr = is_black_attr(h5.token_start, h5.token_len); - } else if (h5.token_type == ATTR_VALUE) { - /* - * IE6,7,8 parsing works a bit differently so - * a whole ", - ">" - "x >", - "' >", - "\">", - "red;", - "red;}", - "red;\"/>", - "');}", - "onerror=alert(1)>", - "x onerror=alert(1);>", - "x' onerror=alert(1);>", - "x\" onerror=alert(1);>", - "", - "", - "", - "", - "", - "", - "123 LIKE -1234.5678E+2;", - "APPLE 19.123 'FOO' \"BAR\"", - "/* BAR */ UNION ALL SELECT (2,3,4)", - "1 || COS(+0X04) --FOOBAR", - "dog apple @cat banana bar", - "dog apple cat \"banana \'bar", - "102 TABLE CLOTH", - "(1001-'1') union select 1,2,3,4 from credit_cards", - NULL - }; - const int imax = 1000000; - int i, j; - size_t slen; - clock_t t0,t1; - double total; - int tps; - - t0 = clock(); - for (i = imax, j=0; i != 0; --i, ++j) { - if (s[j] == NULL) { - j = 0; - } - - slen = strlen(s[j]); - libinjection_xss(s[j], slen); - } - - t1 = clock(); - total = (double) (t1 - t0) / (double) CLOCKS_PER_SEC; - tps = (int)((double) imax / total); - return tps; -} - -int main() -{ - const int mintps = 500000; - int tps = testIsSQL(); - - printf("\nTPS : %d\n\n", tps); - - if (tps < 500000) { - printf("FAIL: %d < %d\n", tps, mintps); - /* FAIL */ - return 1; - } else { - printf("OK: %d > %d\n", tps, mintps); - /* OK */ - return 0; - } -} diff --git a/naxsi_src/ext/libinjection/testdriver.c b/naxsi_src/ext/libinjection/testdriver.c deleted file mode 100644 index 95c01a1..0000000 --- a/naxsi_src/ext/libinjection/testdriver.c +++ /dev/null @@ -1,312 +0,0 @@ -#include -#include -#include -#include -#include -#include "libinjection.h" -#include "libinjection_sqli.h" -#include "libinjection_html5.h" -#include "libinjection_xss.h" - -static char g_test[8096]; -static char g_input[8096]; -static char g_expected[8096]; - -size_t modp_rtrim(char* str, size_t len); -size_t print_string(char* buf, size_t len, stoken_t* t); -size_t print_var(char* buf, size_t len, stoken_t* t); -size_t print_token(char* buf, size_t len, stoken_t *t); -int read_file(const char* fname, int flags, int testtype); -const char* h5_type_to_string(enum html5_type x); -size_t print_html5_token(char* buf, size_t len, h5_state_t* hs); - -size_t modp_rtrim(char* str, size_t len) -{ - while (len) { - char c = str[len -1]; - if (c == ' ' || c == '\n' || c == '\t' || c == '\r') { - str[len -1] = '\0'; - len -= 1; - } else { - break; - } - } - return len; -} - -size_t print_string(char* buf, size_t len, stoken_t* t) -{ - int slen = 0; - - /* print opening quote */ - if (t->str_open != '\0') { - slen = sprintf(buf + len, "%c", t->str_open); - assert(slen >= 0); - len += (size_t) slen; - } - - /* print content */ - slen = sprintf(buf + len, "%s", t->val); - assert(slen >= 0); - len += (size_t) slen; - - /* print closing quote */ - if (t->str_close != '\0') { - slen = sprintf(buf + len, "%c", t->str_close); - assert(slen >= 0); - len += (size_t) slen; - } - - return len; -} - -size_t print_var(char* buf, size_t len, stoken_t* t) -{ - int slen = 0; - if (t->count >= 1) { - slen = sprintf(buf + len, "%c", '@'); - assert(slen >= 0); - len += (size_t) slen; - } - if (t->count == 2) { - slen = sprintf(buf + len, "%c", '@'); - assert(slen >= 0); - len += (size_t) slen; - } - return print_string(buf, len, t); -} - -const char* h5_type_to_string(enum html5_type x) -{ - switch (x) { - case DATA_TEXT: return "DATA_TEXT"; - case TAG_NAME_OPEN: return "TAG_NAME_OPEN"; - case TAG_NAME_CLOSE: return "TAG_NAME_CLOSE"; - case TAG_NAME_SELFCLOSE: return "TAG_NAME_SELFCLOSE"; - case TAG_DATA: return "TAG_DATA"; - case TAG_CLOSE: return "TAG_CLOSE"; - case ATTR_NAME: return "ATTR_NAME"; - case ATTR_VALUE: return "ATTR_VALUE"; - case TAG_COMMENT: return "TAG_COMMENT"; - case DOCTYPE: return "DOCTYPE"; - default: - assert(0); - } -} - -size_t print_html5_token(char* buf, size_t len, h5_state_t* hs) -{ - int slen; - char* tmp = (char*) malloc(hs->token_len + 1); - memcpy(tmp, hs->token_start, hs->token_len); - /* TODO.. encode to be printable */ - tmp[hs->token_len] = '\0'; - - slen = sprintf(buf + len, "%s,%d,%s\n", - h5_type_to_string(hs->token_type), - (int) hs->token_len, - tmp); - len += (size_t) slen; - free(tmp); - return len; -} - -size_t print_token(char* buf, size_t len, stoken_t *t) -{ - int slen; - - slen = sprintf(buf + len, "%c ", t->type); - assert(slen >= 0); - len += (size_t) slen; - switch (t->type) { - case 's': - len = print_string(buf, len, t); - break; - case 'v': - len = print_var(buf, len, t); - break; - default: - slen = sprintf(buf + len, "%s", t->val); - assert(slen >= 0); - len += (size_t) slen; - } - slen = sprintf(buf + len, "%c", '\n'); - assert(slen >= 0); - len += (size_t) slen; - return len; -} - -int read_file(const char* fname, int flags, int testtype) -{ - int count = 0; - FILE *fp = NULL; - char linebuf[8192]; - char g_actual[8192]; - char* bufptr = NULL; - size_t slen; - char* copy; - sfilter sf; - int ok = 1; - int num_tokens; - int issqli; - int i; - - g_test[0] = '\0'; - g_input[0] = '\0'; - g_expected[0] = '\0'; - - fp = fopen(fname, "r"); - while(fgets(linebuf, sizeof(linebuf), fp) != NULL) { - if (count == 0 && strcmp(linebuf, "--TEST--\n") == 0) { - bufptr = g_test; - count = 1; - } else if (count == 1 && strcmp(linebuf, "--INPUT--\n") == 0) { - bufptr = g_input; - count = 2; - } else if (count == 2 && strcmp(linebuf, "--EXPECTED--\n") == 0) { - bufptr = g_expected; - count = 3; - } else { - assert(bufptr != NULL); - strcat(bufptr, linebuf); - } - } - fclose(fp); - if (count != 3) { - return 1; - } - - g_expected[modp_rtrim(g_expected, strlen(g_expected))] = '\0'; - g_input[modp_rtrim(g_input, strlen(g_input))] = '\0'; - - - slen = strlen(g_input); - copy = (char* ) malloc(slen); - memcpy(copy, g_input, slen); - - g_actual[0] = '\0'; - if (testtype == 0) { - /* - * print sqli tokenization only - */ - libinjection_sqli_init(&sf, copy, slen, flags); - libinjection_sqli_callback(&sf, NULL, NULL); - slen =0; - while (libinjection_sqli_tokenize(&sf) == 1) { - slen = print_token(g_actual, slen, sf.current); - } - } else if (testtype == 1) { - /* - * testing tokenization + folding - */ - libinjection_sqli_init(&sf, copy, slen, flags); - libinjection_sqli_callback(&sf, NULL, NULL); - slen =0; - num_tokens = libinjection_sqli_fold(&sf); - for (i = 0; i < num_tokens; ++i) { - slen = print_token(g_actual, slen, libinjection_sqli_get_token(&sf, i)); - } - } else if (testtype == 2) { - /** - * test sqli detection - */ - char buf[100]; - issqli = libinjection_sqli(copy, slen, buf); - if (issqli) { - sprintf(g_actual, "%s", buf); - } - } else if (testtype == 3) { - /* - * test html5 tokenization only - */ - - h5_state_t hs; - libinjection_h5_init(&hs, copy, slen, DATA_STATE); - slen = 0; - while (libinjection_h5_next(&hs)) { - slen = print_html5_token(g_actual, slen, &hs); - } - } else if (testtype == 4) { - /* - * test XSS detection - */ - sprintf(g_actual, "%d", libinjection_xss(copy, slen)); - } else { - fprintf(stderr, "Got stange testtype value of %d\n", testtype); - assert(0); - } - - g_actual[modp_rtrim(g_actual, strlen(g_actual))] = '\0'; - - if (strcmp(g_expected, g_actual) != 0) { - printf("INPUT: \n%s\n==\n", g_input); - printf("EXPECTED: \n%s\n==\n", g_expected); - printf("GOT: \n%s\n==\n", g_actual); - ok = 0; - } - - free(copy); - return ok; -} - -int main(int argc, char** argv) -{ - int offset = 1; - int i; - int ok; - int count = 0; - int count_fail = 0; - int flags = 0; - int testtype = 0; - int quiet = 0; - - const char* fname; - while (1) { - if (strcmp(argv[offset], "-q") == 0 || strcmp(argv[offset], "--quiet") == 0) { - quiet = 1; - offset += 1; - } else { - break; - } - } - - printf("%s\n", libinjection_version()); - - for (i = offset; i < argc; ++i) { - fname = argv[i]; - count += 1; - if (strstr(fname, "test-tokens-")) { - flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; - testtype = 0; - } else if (strstr(fname, "test-folding-")) { - flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; - testtype = 1; - } else if (strstr(fname, "test-sqli-")) { - flags = FLAG_NONE; - testtype = 2; - } else if (strstr(fname, "test-html5-")) { - flags = FLAG_NONE; - testtype = 3; - } else if (strstr(fname, "test-xss-")) { - flags = FLAG_NONE; - testtype = 4; - } else { - fprintf(stderr, "Unknown test type: %s, failing\n", fname); - count_fail += 1; - continue; - } - - ok = read_file(fname, flags, testtype); - if (ok) { - if (! quiet) { - fprintf(stderr, "%s: ok\n", fname); - } - } else { - count_fail += 1; - if (! quiet) { - fprintf(stderr, "%s: fail\n", fname); - } - } - } - return count > 0 && count_fail > 0; -}